一句話:折扣碼是結帳時產生「負應收」的規則;應收真相仍在 order-money-model,本檔只定義折扣碼的適用規則、兌換快照、分潤快照與報表語意。
折扣碼資料分三層:
| 層 | 職責 |
|---|---|
discount_codes | code 本體:可用期間、折扣類型、折扣值、使用上限、分潤規則、啟停狀態。 |
discount_code_trips | 適用範圍:全站或特定 trip(只支援 trip 維度——PK (discount_code_id, trip_id);departure / lodging product 維度未支援,屬未做的未來項)。 |
order_discounts | 訂單成交快照:哪個 code、折多少、誰推薦、分潤快照、當時規則摘要。order_discounts_order_unique(一單一列)⇒ 一張訂單恆只能套一個 code。 |
折扣實際影響應收時,必須同時寫:
order_discounts:保留兌換與分潤快照;order_charge_lines(type='discount', amount_twd=-N, source_type='discount_code', source_id=order_discounts.id):讓金流模型扣應收。order_discounts 是 write-once business snapshot;若折扣套錯,不能改原列,應以反向 charge line / audit 流程修正。
折扣碼可限制:
單碼政策(
stackable是死欄位):discount_codes.stackable欄仍存在,但order_discounts的一單一列 unique 讓「多碼併用」結構上不可能——現行政策即一單一碼,stackable不生效。要開放併用需先放寬 unique(breaking),屆時再賦予此欄語意。
價格通路以成交 line snapshot 為準,不讀取可變的會員分類來重算既有訂單。
結帳時計算順序:
order_charge_lines;payment_schedules,確保 current schedules target 總和等於最新應收。Tour 與 lodging 都走同一原則:
order_lines → tour_booking_lines 的成交快照計算折扣。lodging_nightly_snapshots 與 order_charge_lines(type='lodging_night'),再寫折扣 line。若折扣碼代表 KOL / 合作方推薦,order_discounts 在成交時凍結:
profit_share_twd;分潤付款本身不由本檔建立。需要付款時,由 control-finance 產生 payables(payee_type='other' 或 staff_commission) 與 payable_items,並保留對應 order_discounts 的來源連結。
團控與報表可顯示:
SUM(order_charge_lines.amount_twd);payment_transactions(direction='in'),依報表語意扣除退款或 chargeback;order_discounts.profit_share_twd 中尚未轉 payable 的金額。tour-centric 報表必須經 order_lines → tour_booking_lines 篩 departure;跨產品報表不得用 tour-only join。
order_charge_lines 寫入必須同一交易。redemption_count 更新要 race-safe,避免超用。releaseDiscountRedemptionsForOrder(redemption_count = GREATEST(0, count − 1))——取消單不再吃掉 max_redemptions 名額;per-customer 上限本就以 booking_state <> 'cancelled' 派生計數自癒。failover 轉單不歸還(轉單不是取消釋出,兌換沿鏈保留):transferMainToTarget 把主單的 order_discounts 快照與 discount charge line 一併結轉到新單(redemption_count 不重複累加),新單 gross = 成交價 − 折扣 − 訂金結轉,客戶沿鏈總付款恆等於折後價。order_discounts。本檔描述模型與不變式;精確 schema/DTO 看 code。權威入口:
packages/core/src/schema/business.ts(discount_codes / discount_code_trips / order_discounts)resolveAndApplyDiscountInTx,packages/core/src/discount/repo.tspreviewDiscount,同檔createOrderWithReservation(orders/repo.ts)、lodging createLodgingBooking(lodging/booking-repo.ts)、房升折扣感知 recalculateOrderRoomUpgrade(rooms/repo.ts)