//! Ensures the built-in carrier delivery options (Packeta, DPD) always exist. //! //! These are the only delivery options the shop offers; the admin can price and //! enable/disable them but cannot add or remove options. We insert each one //! only when its `code` is missing, so an admin's price/enabled changes are //! never overwritten on the next boot. use async_trait::async_trait; use loco_rs::prelude::*; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, Set}; use crate::models::shipping_methods; /// `(code, name, carrier, requires_pickup_point, default_price_cents, position)` const BUILTINS: [(&str, &str, &str, bool, i64, i32); 2] = [ ("packeta", "Packeta", "packeta", true, 290, 0), ("dpd", "DPD", "dpd", false, 450, 1), ]; pub struct ShippingSeeder; #[async_trait] impl Initializer for ShippingSeeder { fn name(&self) -> String { "shipping-seeder".to_string() } async fn before_run(&self, ctx: &AppContext) -> Result<()> { for (code, name, carrier, requires_pickup_point, price_cents, position) in BUILTINS { let exists = shipping_methods::Entity::find() .filter(shipping_methods::Column::Code.eq(code)) .count(&ctx.db) .await? > 0; if exists { continue; } shipping_methods::ActiveModel { code: Set(code.to_string()), name: Set(name.to_string()), carrier: Set(carrier.to_string()), requires_pickup_point: Set(requires_pickup_point), price_cents: Set(price_cents), enabled: Set(true), position: Set(position), ..Default::default() } .insert(&ctx.db) .await?; tracing::info!(carrier = code, "seeded built-in delivery option"); } Ok(()) } }