feat(aftersale): per-line refund/return flow with ledger-backed completion (add-aftersale-refunds)
This commit is contained in:
@@ -173,6 +173,8 @@ pub struct Order {
|
||||
pub total_minor: i64,
|
||||
/// Realized coupon discount, converted to the order currency server-side.
|
||||
pub discount_minor: i64,
|
||||
/// Authoritative sum of completed after-sale refunds.
|
||||
pub refund_total_minor: i64,
|
||||
/// The coupon this order redeemed, if any.
|
||||
pub coupon_id: Option<Uuid>,
|
||||
/// Group-buying activity this order joined, if any.
|
||||
@@ -198,6 +200,36 @@ pub struct OrderItem {
|
||||
pub flash_sale_item_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type)]
|
||||
#[sqlx(type_name = "aftersale_kind", rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AftersaleKind {
|
||||
RefundOnly,
|
||||
ReturnRefund,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type)]
|
||||
#[sqlx(type_name = "aftersale_status", rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AftersaleStatus {
|
||||
Pending,
|
||||
Approved,
|
||||
Rejected,
|
||||
BuyerShipping,
|
||||
MerchantConfirmed,
|
||||
Refunded,
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
impl AftersaleStatus {
|
||||
pub fn is_terminal(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
AftersaleStatus::Refunded | AftersaleStatus::Rejected | AftersaleStatus::Cancelled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, sqlx::FromRow)]
|
||||
pub struct Shipment {
|
||||
pub id: Uuid,
|
||||
|
||||
Reference in New Issue
Block a user