# 算錢 ## 定義 | 名字 | 意思 | | -------- | -------- | | set | 套餐菜單 | | menu | 單點菜單 | | item | 餐點 | | subtotal | 小計 | | modifier | 變價 | | mod | 變價 | | rounding | 進位 | | excludeOrderDiscount | 預設不打折扣 | | excludeOrderSurcharge | 預設不收服務費 | |promocode|優惠碼| |coupon|優惠券| |batch|訂單的一次下單| ## 這次整理的重點 讓前端照後端的業務邏輯 算法 訂單收據. 上面的數字 - item x2 **$100** - options - item level modifier - subtotal - order level modifier - surcharge - discount - ricecoin - 總折扣: 負的item+order mod 加總 - shipping: 運費 - ?忘記有沒有顯示運費折扣折多少 - 總計: roundedTotal function 概念 input -> logic -> output f(x)=y ## 計算時機 系統流程 ```mermaid sequenceDiagram User->>Server: request orders Server->>Database: request orders Database->>Server: response orders Server->>Server: calculateOrder Server->>User: response orders User->>User: calculateOrder ``` ## 計算步驟 1. 把訂單放入function 2. sort order level mod 1. logic: 1. primary sort: 1. applyto: product>shipping>all 1. secondary sort: 1. type: Merchant>Surcharge>ShippingDiscount>Discount>Promocode>RiceCoin 3. batches: only status:{submitted,confirmed} 提交跟接單 4. item: 忽略取消的 5. 獲得所有提交跟接單的非取消的食物 6. 每個食物會 GetPrice(useDiscount:false): 1. getBasePrice 3. sort item level mod 5. 計算item level mod calculatedAmount. 3. 後面的mod 會被前面的mod 影響 6. 如果同時有comborule跟merchant. 只會算merchant 7. useDiscount 4. true的話 也會算DISCOUNT 5. false 不會算DISCOUNT subtotal小計: 獲得所有提交跟接單的非取消的食物. 不算order mod, 只算item mod MERCHANT modifierSum所有訂單變價總和: sum of order level mod calculatedAmount 1. 計算每個order level mod calculatedAmount 2. 後面的mod 有機會被前面的影響 3. 順序surcharge> product> shipping> all 4. surcharge: 收服務費的食物的GetPrice(false). 得到calculated Amount 5. product: 可打折扣的食物的GetPrice(false). 6. 折的錢不能超過product的錢 7. 8. eg: 9. 紅茶100 + 綠茶50 + 可樂(eod) 20 全單 -$17 10. base = 可以打折的食物的item.GetPrice(false)的加總 = 150 11. a = 所有 item.GetPrice(false) = 170 12. 攤分 紅茶100-(17/150*100) + 綠茶50-(17/150*100) + 20 13. 加總攤分後結果 b = 147.3333333 14. a-b = ??????? 6. shipping: (shippingfee*(1+mod.percent)+mod.amount)-shippingfee = calculatedAmount 7. ALL: 1. base: item discount後的subtotal+ shippingfee 9. 加 surcharge, product, shipping,all的calculatedAmount 成為新的base 2. (base*(1+mod.percent)+mod.amount)-base = calculatedAmount 3. 把order level mod calcualtedAmount 加起來 itemDiscountTotal所有item折扣總和: sum of item level mod discount calculatedAmount roundedTotal總計: round(subtotal+shippingfee+modifierSum-itemDiscountTotal) ### 定義常用欄位 - item.GetBasePrice(): price - discount - specialDiscount(沒在用) + sum(options price* quantity) 紅茶100-20 + options[珍珠(1*5)+布丁(2*5)] = 95 - item.GetPrice(true) basePrice + merchant + discount - item.GetPrice(false) basePrice + merchant sorting case1: order.items = [A:100,B:100] order.modifers = [ {type:"ALL",amount:-200,calculatedAmount:0}, {type:"PRODUCT", amount:-200,calcultedAmount:-200}, ] case2: ? order.items = [A:100,B:100] order.modifers = [ {type:"ALL",percent:-20,calculatedAmount:}, // 180*(1-20%)=144 {type:"PRODUCT", amount:-20,calcultedAmount:-20}, // 200-20=180 ] ## background modifier 屬性: - amount: number - -$10 coupon. amount=-10 - percent: number - -20% discount, percent=-20 - maxAmount: number - -10% coupon, 最多折100. - override: bool true/false - 應該沒在使用 - true: - 當訂單需要重新計算, 直接相信calculatedAmount - false: 一般都是false - 當訂單需要重新計算, 請重新計算 - overrideItem - 忽略item的excludeOrderDiscount/excludeOrderSurcharge - calculatedAmount - 儲存計算結果 - offeredBy - 影響statement report - value: DimOrder/Merchant modifier level等級: - item - order modifier type種類: - RICECOIN - 代表ricecoin - eg: {type:"RICECOIN",amount:-100,applyTo:"ALL"} - order level only - 不會有percent. 不會applyTo:product/shipping - PROMOCODE - promocode,coupon - eg: {type:"PROMOCODE",} - order level only - 有機會有amount, percent, applyTo:"ALL"/"SHIPPING"/"PRODUCT" - DISCOUNT - 餐廳員工輸入的折扣 - order,item level only - eg: {type:"DISCOUNT",percent:-10,applyTo:"PRODUCT"} - 有amount, percent - applyTo:"PRODUCT" - SURCHARGE - 服務費 (manual>枱號群>開放時間>預設) - order level only - eg: {type:"SURCHARGE",percent:10,applyTo:"PRODUCT"} - 有percent - applyTo:"PRODUCT" - SHIPPING_DISCOUNT - 餐廳提供的運費折扣 - 運費折扣由來: - promocode/coupon applyTo:"shipping" - merchant.shipping - eg: {type:"SHIPPING_DISCOUNT",offeredBy: "Merchant",amount} - 一定是amount - order level only - MERCHANT - 改價 - item level only - eg: {type:"MERCHANT",offeredBy:"Merchant",amount:-} - 原價100, 改成20. amount=-80 - COMBORULE - 撞餐. 組合優惠 - comborule, 買A送B - X comborule: itemA: 10$, item B: 20$. = 30$ - O comborule: itemA: 10$, item B: 20$. = 10$ - item B 身上會有item modifier. {type:"COMBORULE",amount:-20} modifier applyTo 作用於: - PRODUCT - 只折食物 - SHIPPING - 只折運費 - ALL - 食物運費都折 rounding: 1. type 1. up 2. down 3. off 4. '' 3. digit 1. 0,1,2,3 四捨五入 digit=0, type=off. 0.4=>0, 0.5=>1 無條件上捨 digit=0, type=up. 0.1=>1 無條件下捨 digit=0, type=down. 0.9=>0 無條件下捨 digit=1, type=down. 0.99=>0.9