wip(freight): migration 0017 + model/column-list groundwork for add-freight-templates

This commit is contained in:
Chengdong Zhang
2026-09-23 17:39:45 +08:00
parent a83e857bdf
commit 5b426486ac
105 changed files with 6193 additions and 1566 deletions
+15
View File
@@ -110,6 +110,8 @@ pub struct Sku {
pub price_minor: i64,
pub currency: String,
pub stock: i32,
/// Grams per unit for by-weight freight; null lines contribute zero weight.
pub weight_grams: Option<i32>,
pub active: bool,
}
@@ -175,6 +177,8 @@ pub struct Order {
pub discount_minor: i64,
/// Authoritative sum of completed after-sale refunds.
pub refund_total_minor: i64,
/// Server-computed per-shop-order shipping fee.
pub shipping_fee_minor: i64,
/// The coupon this order redeemed, if any.
pub coupon_id: Option<Uuid>,
/// Group-buying activity this order joined, if any.
@@ -198,6 +202,9 @@ pub struct OrderItem {
pub qty: i32,
/// Set when this line received flash-sale pricing.
pub flash_sale_item_id: Option<Uuid>,
/// Freight template + pricing method snapshotted at checkout.
pub freight_template_id: Option<Uuid>,
pub freight_pricing_method: Option<FreightPricingMethod>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type)]
@@ -230,6 +237,14 @@ impl AftersaleStatus {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type)]
#[sqlx(type_name = "freight_pricing_method", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum FreightPricingMethod {
ByPiece,
ByWeight,
}
#[derive(Debug, Clone, Serialize, sqlx::FromRow)]
pub struct Shipment {
pub id: Uuid,
+4 -3
View File
@@ -9,10 +9,11 @@ use crate::models::{Order, OrderItem, OrderStatus};
use super::dto::{OrderScope, OrderView};
const ORDER_COLS: &str = "id, order_no, shop_id, user_id, status, currency, total_minor,
discount_minor, refund_total_minor, coupon_id, group_activity_id, group_id, shipping_address,
created_at, updated_at";
discount_minor, refund_total_minor, shipping_fee_minor, coupon_id, group_activity_id,
group_id, shipping_address, created_at, updated_at";
const ORDER_ITEM_COLS: &str =
"id, order_id, sku_id, product_name, sku_code, image, unit_price_minor, qty, flash_sale_item_id";
"id, order_id, sku_id, product_name, sku_code, image, unit_price_minor, qty, flash_sale_item_id,
freight_template_id, freight_pricing_method";
pub async fn attach_items(db: &PgPool, orders: Vec<Order>) -> ApiResult<Vec<OrderView>> {
let ids: Vec<Uuid> = orders.iter().map(|o| o.id).collect();
+1
View File
@@ -68,4 +68,5 @@ pub struct SkuBody {
pub currency: String,
pub stock: i32,
pub active: Option<bool>,
pub weight_grams: Option<i32>,
}
+2 -2
View File
@@ -26,7 +26,7 @@ pub async fn attach_skus(
Vec::new()
} else if public_only {
sqlx::query_as::<_, Sku>(
"SELECT id, product_id, sku_code, attributes, price_minor, currency, stock, active
"SELECT id, product_id, sku_code, attributes, price_minor, currency, stock, weight_grams, active
FROM skus WHERE product_id = ANY($1) AND active = TRUE ORDER BY sku_code",
)
.bind(&ids)
@@ -34,7 +34,7 @@ pub async fn attach_skus(
.await?
} else {
sqlx::query_as::<_, Sku>(
"SELECT id, product_id, sku_code, attributes, price_minor, currency, stock, active
"SELECT id, product_id, sku_code, attributes, price_minor, currency, stock, weight_grams, active
FROM skus WHERE product_id = ANY($1) ORDER BY sku_code",
)
.bind(&ids)
+5 -4
View File
@@ -297,11 +297,11 @@ pub async fn upsert_sku(
)));
}
Ok(sqlx::query_as::<_, Sku>(
"INSERT INTO skus (product_id, sku_code, attributes, price_minor, currency, stock, active)
VALUES ($1, $2, $3, $4, $5, $6, $7)
"INSERT INTO skus (product_id, sku_code, attributes, price_minor, currency, stock, active, weight_grams)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (product_id, sku_code)
DO UPDATE SET attributes = $3, price_minor = $4, currency = $5, stock = $6, active = $7
RETURNING id, product_id, sku_code, attributes, price_minor, currency, stock, active",
DO UPDATE SET attributes = $3, price_minor = $4, currency = $5, stock = $6, active = $7, weight_grams = $8
RETURNING id, product_id, sku_code, attributes, price_minor, currency, stock, weight_grams, active",
)
.bind(product_id)
.bind(body.sku_code.trim())
@@ -310,6 +310,7 @@ pub async fn upsert_sku(
.bind(&currency)
.bind(body.stock)
.bind(body.active.unwrap_or(true))
.bind(body.weight_grams)
.fetch_one(&state.db)
.await?)
}