# 算錢
## 定義
| 名字 | 意思 |
| -------- | -------- |
| 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