@pisell/pisellos 0.0.567 → 0.0.569
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.js +6 -9
- package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
- package/dist/model/strategy/adapter/walletPass/example.js +3 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +7 -7
- package/dist/model/strategy/strategy-example.js +5 -19
- package/dist/modules/BaseModule.d.ts +2 -2
- package/dist/modules/BaseModule.js +4 -4
- package/dist/modules/BookingContext/index.d.ts +48 -0
- package/dist/modules/BookingContext/index.js +566 -0
- package/dist/modules/BookingContext/types.d.ts +102 -0
- package/dist/modules/BookingContext/types.js +51 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +302 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +149 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +249 -0
- package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/dist/modules/BookingContext/utils/flexible.js +56 -0
- package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
- package/dist/modules/BookingContext/utils/index.d.ts +11 -0
- package/dist/modules/BookingContext/utils/index.js +11 -0
- package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/dist/modules/BookingContext/utils/noResource.js +77 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
- package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/dist/modules/BookingContext/utils/productExtend.js +339 -0
- package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
- package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
- package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
- package/dist/modules/BookingContext/utils/resources.js +486 -0
- package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
- package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
- package/dist/modules/Cart/index.js +0 -3
- package/dist/modules/Cart/utils/cartProduct.js +26 -6
- package/dist/modules/Cart/utils/changePrice.js +27 -20
- package/dist/modules/Customer/index.d.ts +20 -0
- package/dist/modules/Customer/index.js +172 -83
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Date/index.js +1 -5
- package/dist/modules/Discount/index.d.ts +2 -1
- package/dist/modules/Discount/index.js +37 -12
- package/dist/modules/Discount/types.d.ts +1 -0
- package/dist/modules/OpenData/index.d.ts +8 -0
- package/dist/modules/OpenData/index.js +35 -17
- package/dist/modules/Order/index.d.ts +449 -24
- package/dist/modules/Order/index.js +5437 -608
- package/dist/modules/Order/types.d.ts +693 -88
- package/dist/modules/Order/types.js +68 -1
- package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
- package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
- package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
- package/dist/modules/Order/utils/manualProductDiscount.js +210 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
- package/dist/modules/Order/utils.d.ts +167 -18
- package/dist/modules/Order/utils.js +960 -165
- package/dist/modules/Payment/index.d.ts +10 -9
- package/dist/modules/Payment/index.js +508 -874
- package/dist/modules/Payment/types.d.ts +40 -16
- package/dist/modules/Payment/utils.d.ts +1 -1
- package/dist/modules/Payment/utils.js +4 -3
- package/dist/modules/Payment/walletpass.js +48 -34
- package/dist/modules/Product/types.d.ts +29 -7
- package/dist/modules/ProductList/index.d.ts +17 -13
- package/dist/modules/ProductList/index.js +184 -74
- package/dist/modules/ProductList/types.d.ts +17 -0
- package/dist/modules/Quotation/index.d.ts +22 -2
- package/dist/modules/Quotation/index.js +108 -42
- package/dist/modules/Quotation/types.d.ts +19 -0
- package/dist/modules/ResourcePlanner/index.d.ts +24 -0
- package/dist/modules/ResourcePlanner/index.js +181 -0
- package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
- package/dist/modules/ResourcePlanner/planner.js +1069 -0
- package/dist/modules/ResourcePlanner/types.d.ts +227 -0
- package/dist/modules/ResourcePlanner/types.js +1 -0
- package/dist/modules/Rules/index.d.ts +8 -10
- package/dist/modules/Rules/index.js +219 -114
- package/dist/modules/Rules/types.d.ts +14 -3
- package/dist/modules/SalesSummary/index.d.ts +23 -26
- package/dist/modules/SalesSummary/index.js +152 -46
- package/dist/modules/SalesSummary/types.d.ts +9 -1
- package/dist/modules/SalesSummary/utils.d.ts +3 -22
- package/dist/modules/SalesSummary/utils.js +803 -163
- package/dist/modules/Schedule/getDateIsInSchedule.js +14 -7
- package/dist/modules/Schedule/index.d.ts +18 -5
- package/dist/modules/Schedule/index.js +78 -24
- package/dist/modules/Schedule/types.d.ts +2 -0
- package/dist/modules/Schedule/utils.js +0 -1
- package/dist/modules/Step/index.js +0 -1
- package/dist/modules/Summary/index.js +4 -3
- package/dist/modules/SurchargeList/index.d.ts +18 -0
- package/dist/modules/SurchargeList/index.js +185 -0
- package/dist/modules/SurchargeList/types.d.ts +15 -0
- package/dist/modules/SurchargeList/types.js +1 -0
- package/dist/modules/index.d.ts +3 -0
- package/dist/modules/index.js +4 -1
- package/dist/plugins/app.d.ts +2 -0
- package/dist/plugins/request.d.ts +1 -0
- package/dist/plugins/request.js +1 -4
- package/dist/plugins/window.js +2 -6
- package/dist/server/index.d.ts +462 -8
- package/dist/server/index.js +6137 -714
- package/dist/server/modules/floor-plan/index.d.ts +39 -0
- package/dist/server/modules/floor-plan/index.js +595 -0
- package/dist/server/modules/floor-plan/types.d.ts +43 -0
- package/dist/server/modules/floor-plan/types.js +13 -0
- package/dist/server/modules/index.d.ts +7 -2
- package/dist/server/modules/index.js +6 -0
- package/dist/server/modules/menu/index.js +32 -41
- package/dist/server/modules/order/index.d.ts +207 -14
- package/dist/server/modules/order/index.js +2326 -379
- package/dist/server/modules/order/types.d.ts +76 -5
- package/dist/server/modules/order/types.js +14 -1
- package/dist/server/modules/order/utils/filterBookings.d.ts +7 -1
- package/dist/server/modules/order/utils/filterBookings.js +118 -11
- package/dist/server/modules/order/utils/filterOrders.js +242 -14
- package/dist/server/modules/payment/index.d.ts +28 -0
- package/dist/server/modules/payment/index.js +305 -0
- package/dist/server/modules/payment/types.d.ts +9 -0
- package/dist/server/modules/payment/types.js +1 -0
- package/dist/server/modules/products/index.d.ts +105 -14
- package/dist/server/modules/products/index.js +1397 -540
- package/dist/server/modules/products/types.d.ts +34 -1
- package/dist/server/modules/products/types.js +4 -0
- package/dist/server/modules/quotation/index.d.ts +39 -0
- package/dist/server/modules/quotation/index.js +289 -86
- package/dist/server/modules/resource/index.d.ts +2 -3
- package/dist/server/modules/resource/index.js +105 -84
- package/dist/server/modules/schedule/index.d.ts +6 -4
- package/dist/server/modules/schedule/index.js +137 -114
- package/dist/server/test.json +713 -0
- package/dist/server/types.d.ts +2 -0
- package/dist/server/utils/product.js +2 -3
- package/dist/server/utils/small-ticket.d.ts +71 -0
- package/dist/server/utils/small-ticket.js +963 -0
- package/dist/solution/BaseSales/index.d.ts +378 -0
- package/dist/solution/BaseSales/index.js +4006 -0
- package/dist/solution/BaseSales/types.d.ts +394 -0
- package/dist/solution/BaseSales/types.js +40 -0
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
- package/dist/solution/BaseSales/utils/cartPromotion.js +1450 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +157 -0
- package/dist/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
- package/dist/solution/BaseSales/utils/quotationPrice.js +250 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +218 -0
- package/dist/solution/BaseSales/utils.d.ts +40 -0
- package/dist/solution/BaseSales/utils.js +263 -0
- package/dist/solution/BookingByStep/index.js +7 -59
- package/dist/solution/BookingByStep/utils/capacity.js +1 -11
- package/dist/solution/BookingByStep/utils/resources.js +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
- package/dist/solution/BookingTicket/index.d.ts +393 -24
- package/dist/solution/BookingTicket/index.js +2506 -445
- package/dist/solution/BookingTicket/types.d.ts +191 -6
- package/dist/solution/BookingTicket/types.js +83 -10
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
- package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
- package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
- package/dist/solution/BookingTicket/utils/addTimeAvailability.js +95 -0
- package/dist/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
- package/dist/solution/BookingTicket/utils/bookingStatus.js +136 -0
- package/dist/solution/BookingTicket/utils/cartView.d.ts +29 -0
- package/dist/solution/BookingTicket/utils/cartView.js +209 -0
- package/dist/solution/BookingTicket/utils/exampleData.d.ts +123 -0
- package/dist/solution/BookingTicket/utils/exampleData.js +183 -0
- package/dist/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
- package/dist/solution/BookingTicket/utils/orderCustomer.js +31 -0
- package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
- package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.js +438 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +400 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +41 -1
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
- package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +36 -34
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +26 -18
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
- package/dist/solution/BuyTickets/index.js +9 -12
- package/dist/solution/Checkout/index.d.ts +1 -0
- package/dist/solution/Checkout/index.js +199 -277
- package/dist/solution/Checkout/utils/index.js +8 -20
- package/dist/solution/RegisterAndLogin/config.js +2 -10
- package/dist/solution/RegisterAndLogin/index.js +30 -76
- package/dist/solution/Sales/index.d.ts +50 -5
- package/dist/solution/Sales/index.js +484 -92
- package/dist/solution/Sales/types.d.ts +26 -2
- package/dist/solution/ScanOrder/index.d.ts +27 -21
- package/dist/solution/ScanOrder/index.js +509 -454
- package/dist/solution/ScanOrder/types.d.ts +33 -11
- package/dist/solution/ScanOrder/types.js +4 -5
- package/dist/solution/ScanOrder/utils.d.ts +4 -1
- package/dist/solution/ScanOrder/utils.js +109 -34
- package/dist/solution/ShopDiscount/index.js +6 -11
- package/dist/solution/UnifiedBookingSales/index.d.ts +183 -0
- package/dist/solution/UnifiedBookingSales/index.js +1871 -0
- package/dist/solution/UnifiedBookingSales/types.d.ts +143 -0
- package/dist/solution/UnifiedBookingSales/types.js +11 -0
- package/dist/solution/VenueBooking/index.d.ts +34 -20
- package/dist/solution/VenueBooking/index.js +630 -505
- package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +9 -3
- package/dist/solution/index.d.ts +2 -0
- package/dist/solution/index.js +3 -1
- package/dist/types/index.d.ts +11 -1
- package/dist/utils/task.js +15 -18
- package/dist/utils/watch.js +0 -1
- package/lib/apis/picoding.js +2 -0
- package/lib/core/index.js +130 -131
- package/lib/effects/index.js +46 -57
- package/lib/index.js +92 -53
- package/lib/model/index.js +14 -21
- package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
- package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
- package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
- package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
- package/lib/model/strategy/adapter/index.js +100 -64
- package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
- package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
- package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
- package/lib/model/strategy/adapter/itemRule/index.js +83 -57
- package/lib/model/strategy/adapter/itemRule/type.js +97 -36
- package/lib/model/strategy/adapter/promotion/adapter.js +84 -63
- package/lib/model/strategy/adapter/promotion/evaluator.js +383 -232
- package/lib/model/strategy/adapter/promotion/examples.js +139 -159
- package/lib/model/strategy/adapter/promotion/index.js +1 -49
- package/lib/model/strategy/adapter/promotion/type.js +199 -35
- package/lib/model/strategy/adapter/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -152
- package/lib/model/strategy/adapter/walletPass/example.js +217 -190
- package/lib/model/strategy/adapter/walletPass/index.js +75 -51
- package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
- package/lib/model/strategy/adapter/walletPass/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/utils.js +654 -402
- package/lib/model/strategy/engine.js +270 -168
- package/lib/model/strategy/index.js +49 -34
- package/lib/model/strategy/strategy-example.js +243 -239
- package/lib/model/strategy/type.js +100 -40
- package/lib/modules/Account/index.js +39 -53
- package/lib/modules/Account/types.js +20 -33
- package/lib/modules/AccountList/index.js +116 -154
- package/lib/modules/AccountList/types.js +30 -31
- package/lib/modules/AccountList/utils.js +18 -30
- package/lib/modules/BaseModule.d.ts +2 -2
- package/lib/modules/BaseModule.js +26 -49
- package/lib/modules/BookingContext/index.d.ts +48 -0
- package/lib/modules/BookingContext/index.js +390 -0
- package/lib/modules/BookingContext/types.d.ts +102 -0
- package/lib/modules/BookingContext/types.js +48 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +286 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +148 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +242 -0
- package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/lib/modules/BookingContext/utils/flexible.js +63 -0
- package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/lib/modules/BookingContext/utils/formatResourceList.js +35 -0
- package/lib/modules/BookingContext/utils/index.d.ts +11 -0
- package/lib/modules/BookingContext/utils/index.js +126 -0
- package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/lib/modules/BookingContext/utils/noResource.js +78 -0
- package/lib/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +29 -0
- package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/lib/modules/BookingContext/utils/productExtend.js +330 -0
- package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
- package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/lib/modules/BookingContext/utils/resourceSelection.js +24 -0
- package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
- package/lib/modules/BookingContext/utils/resources.js +419 -0
- package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/lib/modules/BookingContext/utils/serviceTimes.js +161 -0
- package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/lib/modules/BookingContext/utils/timeSlices.js +114 -0
- package/lib/modules/Cart/index.js +170 -124
- package/lib/modules/Cart/types.js +46 -51
- package/lib/modules/Cart/utils/cartAccount.js +40 -39
- package/lib/modules/Cart/utils/cartDate.js +56 -61
- package/lib/modules/Cart/utils/cartDiscount.js +28 -33
- package/lib/modules/Cart/utils/cartNote.js +27 -32
- package/lib/modules/Cart/utils/cartProduct.js +331 -244
- package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
- package/lib/modules/Cart/utils/cartResource.js +72 -78
- package/lib/modules/Cart/utils/changePrice.js +37 -67
- package/lib/modules/Cart/utils/index.js +106 -48
- package/lib/modules/Customer/constants.js +13 -34
- package/lib/modules/Customer/index.d.ts +20 -0
- package/lib/modules/Customer/index.js +270 -154
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Customer/types.js +38 -35
- package/lib/modules/Date/index.js +116 -115
- package/lib/modules/Date/types.js +16 -28
- package/lib/modules/Date/utils.js +174 -123
- package/lib/modules/Discount/index.d.ts +2 -1
- package/lib/modules/Discount/index.js +133 -113
- package/lib/modules/Discount/types.d.ts +1 -0
- package/lib/modules/Discount/types.js +9 -31
- package/lib/modules/Guests/index.js +30 -56
- package/lib/modules/Guests/types.js +23 -33
- package/lib/modules/Holder/index.js +209 -189
- package/lib/modules/Holder/types.js +4 -16
- package/lib/modules/Holder/utils.js +20 -49
- package/lib/modules/OpenData/index.d.ts +8 -0
- package/lib/modules/OpenData/index.js +81 -74
- package/lib/modules/OpenData/types.js +4 -16
- package/lib/modules/OpenData/utils.js +44 -78
- package/lib/modules/Order/index.d.ts +449 -24
- package/lib/modules/Order/index.js +3834 -489
- package/lib/modules/Order/types.d.ts +693 -88
- package/lib/modules/Order/types.js +78 -33
- package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
- package/lib/modules/Order/utils/bundleDiscountHydration.js +106 -0
- package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
- package/lib/modules/Order/utils/manualProductDiscount.js +207 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +353 -0
- package/lib/modules/Order/utils.d.ts +167 -18
- package/lib/modules/Order/utils.js +1247 -345
- package/lib/modules/Payment/cash.js +20 -33
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
- package/lib/modules/Payment/eftpos.js +16 -30
- package/lib/modules/Payment/index.d.ts +10 -9
- package/lib/modules/Payment/index.js +542 -502
- package/lib/modules/Payment/mx51.js +1 -0
- package/lib/modules/Payment/types.d.ts +40 -16
- package/lib/modules/Payment/types.js +216 -107
- package/lib/modules/Payment/utils.d.ts +1 -1
- package/lib/modules/Payment/utils.js +53 -49
- package/lib/modules/Payment/walletpass.js +231 -203
- package/lib/modules/Product/index.js +51 -46
- package/lib/modules/Product/types.d.ts +29 -7
- package/lib/modules/Product/types.js +4 -16
- package/lib/modules/Product/utils.js +32 -33
- package/lib/modules/ProductList/index.d.ts +17 -13
- package/lib/modules/ProductList/index.js +160 -118
- package/lib/modules/ProductList/types.d.ts +17 -0
- package/lib/modules/ProductList/types.js +9 -31
- package/lib/modules/Quotation/index.d.ts +22 -2
- package/lib/modules/Quotation/index.js +123 -89
- package/lib/modules/Quotation/types.d.ts +19 -0
- package/lib/modules/Quotation/types.js +4 -16
- package/lib/modules/Resource/index.js +27 -59
- package/lib/modules/Resource/types.js +22 -32
- package/lib/modules/Resource/utils.js +30 -38
- package/lib/modules/ResourcePlanner/index.d.ts +24 -0
- package/lib/modules/ResourcePlanner/index.js +147 -0
- package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
- package/lib/modules/ResourcePlanner/planner.js +895 -0
- package/lib/modules/ResourcePlanner/types.d.ts +227 -0
- package/lib/modules/ResourcePlanner/types.js +5 -0
- package/lib/modules/Rules/index.d.ts +8 -10
- package/lib/modules/Rules/index.js +1286 -894
- package/lib/modules/Rules/types.d.ts +14 -3
- package/lib/modules/Rules/types.js +17 -40
- package/lib/modules/SalesSummary/index.d.ts +23 -26
- package/lib/modules/SalesSummary/index.js +130 -71
- package/lib/modules/SalesSummary/types.d.ts +9 -1
- package/lib/modules/SalesSummary/types.js +4 -16
- package/lib/modules/SalesSummary/utils.d.ts +3 -22
- package/lib/modules/SalesSummary/utils.js +738 -250
- package/lib/modules/ScanOrderLogger/index.js +59 -79
- package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
- package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
- package/lib/modules/ScanOrderLogger/types.js +4 -16
- package/lib/modules/Schedule/getDateIsInSchedule.js +345 -171
- package/lib/modules/Schedule/index.d.ts +18 -5
- package/lib/modules/Schedule/index.js +139 -114
- package/lib/modules/Schedule/type.js +4 -16
- package/lib/modules/Schedule/types.d.ts +2 -0
- package/lib/modules/Schedule/types.js +4 -16
- package/lib/modules/Schedule/utils.js +433 -291
- package/lib/modules/Step/index.js +40 -52
- package/lib/modules/Step/tyeps.js +4 -16
- package/lib/modules/Summary/index.js +66 -70
- package/lib/modules/Summary/types.js +4 -16
- package/lib/modules/Summary/utils.js +782 -429
- package/lib/modules/SurchargeList/index.d.ts +18 -0
- package/lib/modules/SurchargeList/index.js +95 -0
- package/lib/modules/SurchargeList/types.d.ts +15 -0
- package/lib/modules/SurchargeList/types.js +5 -0
- package/lib/modules/index.d.ts +3 -0
- package/lib/modules/index.js +245 -57
- package/lib/plugins/app.d.ts +2 -0
- package/lib/plugins/app.js +4 -16
- package/lib/plugins/index.js +36 -25
- package/lib/plugins/request.d.ts +1 -0
- package/lib/plugins/request.js +137 -126
- package/lib/plugins/shopStore.js +4 -16
- package/lib/plugins/user.js +4 -16
- package/lib/plugins/window.js +171 -179
- package/lib/server/index.d.ts +462 -8
- package/lib/server/index.js +4668 -713
- package/lib/server/modules/floor-plan/index.d.ts +39 -0
- package/lib/server/modules/floor-plan/index.js +306 -0
- package/lib/server/modules/floor-plan/types.d.ts +43 -0
- package/lib/server/modules/floor-plan/types.js +19 -0
- package/lib/server/modules/index.d.ts +7 -2
- package/lib/server/modules/index.js +106 -59
- package/lib/server/modules/menu/index.js +146 -122
- package/lib/server/modules/menu/types.js +18 -31
- package/lib/server/modules/order/index.d.ts +207 -14
- package/lib/server/modules/order/index.js +1463 -316
- package/lib/server/modules/order/types.d.ts +76 -5
- package/lib/server/modules/order/types.js +117 -32
- package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
- package/lib/server/modules/order/utils/filterBookings.js +288 -146
- package/lib/server/modules/order/utils/filterOrders.js +318 -64
- package/lib/server/modules/payment/index.d.ts +28 -0
- package/lib/server/modules/payment/index.js +168 -0
- package/lib/server/modules/payment/types.d.ts +9 -0
- package/lib/server/modules/payment/types.js +5 -0
- package/lib/server/modules/products/index.d.ts +105 -14
- package/lib/server/modules/products/index.js +969 -383
- package/lib/server/modules/products/types.d.ts +34 -1
- package/lib/server/modules/products/types.js +44 -34
- package/lib/server/modules/quotation/index.d.ts +39 -0
- package/lib/server/modules/quotation/index.js +220 -77
- package/lib/server/modules/quotation/types.js +21 -31
- package/lib/server/modules/resource/index.d.ts +2 -3
- package/lib/server/modules/resource/index.js +269 -214
- package/lib/server/modules/resource/types.js +42 -33
- package/lib/server/modules/schedule/index.d.ts +6 -4
- package/lib/server/modules/schedule/index.js +158 -132
- package/lib/server/modules/schedule/types.js +14 -21
- package/lib/server/modules/schedule/utils.js +334 -163
- package/lib/server/test.json +713 -0
- package/lib/server/types.d.ts +2 -0
- package/lib/server/types.js +4 -16
- package/lib/server/utils/index.js +25 -23
- package/lib/server/utils/product.js +197 -140
- package/lib/server/utils/schedule.js +34 -41
- package/lib/server/utils/small-ticket.d.ts +71 -0
- package/lib/server/utils/small-ticket.js +926 -0
- package/lib/server/utils/time.js +40 -49
- package/lib/solution/BaseSales/index.d.ts +378 -0
- package/lib/solution/BaseSales/index.js +2367 -0
- package/lib/solution/BaseSales/types.d.ts +394 -0
- package/lib/solution/BaseSales/types.js +47 -0
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
- package/lib/solution/BaseSales/utils/cartPromotion.js +1155 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +140 -0
- package/lib/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
- package/lib/solution/BaseSales/utils/quotationPrice.js +231 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +215 -0
- package/lib/solution/BaseSales/utils.d.ts +40 -0
- package/lib/solution/BaseSales/utils.js +259 -0
- package/lib/solution/BookingByStep/index.js +1530 -1343
- package/lib/solution/BookingByStep/types.js +40 -99
- package/lib/solution/BookingByStep/utils/capacity.js +192 -160
- package/lib/solution/BookingByStep/utils/products.js +42 -52
- package/lib/solution/BookingByStep/utils/resources.js +527 -330
- package/lib/solution/BookingByStep/utils/stock.js +65 -44
- package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
- package/lib/solution/BookingTicket/index.d.ts +393 -24
- package/lib/solution/BookingTicket/index.js +1459 -160
- package/lib/solution/BookingTicket/types.d.ts +191 -6
- package/lib/solution/BookingTicket/types.js +101 -66
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
- package/lib/solution/BookingTicket/utils/addProductDecision.js +353 -0
- package/lib/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +94 -0
- package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
- package/lib/solution/BookingTicket/utils/bookingStatus.js +136 -0
- package/lib/solution/BookingTicket/utils/cartView.d.ts +29 -0
- package/lib/solution/BookingTicket/utils/cartView.js +200 -0
- package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
- package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.js +35 -0
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +387 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +220 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +85 -80
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +64 -0
- package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -80
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +103 -95
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +115 -0
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +83 -0
- package/lib/solution/BuyTickets/index.js +67 -70
- package/lib/solution/BuyTickets/types.js +22 -38
- package/lib/solution/Checkout/index.d.ts +1 -0
- package/lib/solution/Checkout/index.js +1461 -1169
- package/lib/solution/Checkout/types.js +91 -61
- package/lib/solution/Checkout/utils/index.js +228 -159
- package/lib/solution/PlaceOrder/index.js +55 -0
- package/lib/solution/RegisterAndLogin/config.js +495 -470
- package/lib/solution/RegisterAndLogin/index.js +633 -630
- package/lib/solution/RegisterAndLogin/types.js +189 -76
- package/lib/solution/RegisterAndLogin/utils.js +183 -125
- package/lib/solution/Sales/index.d.ts +50 -5
- package/lib/solution/Sales/index.js +495 -220
- package/lib/solution/Sales/types.d.ts +26 -2
- package/lib/solution/Sales/types.js +27 -33
- package/lib/solution/ScanOrder/index.d.ts +27 -21
- package/lib/solution/ScanOrder/index.js +908 -904
- package/lib/solution/ScanOrder/types.d.ts +33 -11
- package/lib/solution/ScanOrder/types.js +33 -34
- package/lib/solution/ScanOrder/utils.d.ts +4 -1
- package/lib/solution/ScanOrder/utils.js +457 -344
- package/lib/solution/ShopDiscount/index.js +230 -236
- package/lib/solution/ShopDiscount/types.js +15 -37
- package/lib/solution/ShopDiscount/utils.js +309 -172
- package/lib/solution/UnifiedBookingSales/index.d.ts +183 -0
- package/lib/solution/UnifiedBookingSales/index.js +1050 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +143 -0
- package/lib/solution/UnifiedBookingSales/types.js +14 -0
- package/lib/solution/VenueBooking/index.d.ts +34 -20
- package/lib/solution/VenueBooking/index.js +982 -950
- package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/lib/solution/VenueBooking/types.js +20 -40
- package/lib/solution/VenueBooking/utils/dateSummary.js +22 -54
- package/lib/solution/VenueBooking/utils/resource.js +31 -54
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +96 -108
- package/lib/solution/VenueBooking/utils/smartPricing.js +112 -100
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -132
- package/lib/solution/VenueBooking/utils.js +130 -67
- package/lib/solution/index.d.ts +2 -0
- package/lib/solution/index.js +124 -37
- package/lib/store/createStore.js +32 -29
- package/lib/types/index.d.ts +11 -1
- package/lib/types/index.js +4 -16
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +81 -47
- package/package.json +2 -1
- package/dist/solution/Checkout/appointmentDemo.json +0 -1
- package/lib/solution/Checkout/appointmentDemo.json +0 -1
|
@@ -1,111 +1,665 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "buildManualProductDiscountItem", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _manualProductDiscount.buildManualProductDiscountItem;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.buildSubmitPayload = buildSubmitPayload;
|
|
13
|
+
exports.calculateOrderProductsDeposit = calculateOrderProductsDeposit;
|
|
14
|
+
exports.clearTempOrderHolderAssignments = clearTempOrderHolderAssignments;
|
|
15
|
+
exports.composeLinePrice = composeLinePrice;
|
|
16
|
+
exports.createDefaultOrderRulesHooks = createDefaultOrderRulesHooks;
|
|
17
|
+
exports.createDefaultTempOrder = createDefaultTempOrder;
|
|
18
|
+
Object.defineProperty(exports, "createEmptySummary", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _utils2.createEmptySummary;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "createUuidV4", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _orderCollectionIdentity.createUuidV4;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
exports.ensureCartItemOriginHolder = ensureCartItemOriginHolder;
|
|
31
|
+
Object.defineProperty(exports, "ensureManualProductDiscountList", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return _manualProductDiscount.ensureManualProductDiscountList;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
exports.ensureProductSku = ensureProductSku;
|
|
38
|
+
Object.defineProperty(exports, "findManualProductDiscountItem", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function () {
|
|
41
|
+
return _manualProductDiscount.findManualProductDiscountItem;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
exports.formatDateTime = formatDateTime;
|
|
45
|
+
exports.formatV1Product = formatV1Product;
|
|
46
|
+
exports.getAllDiscountList = exports.generateDuration = void 0;
|
|
47
|
+
exports.getBundleSellingMagnitude = getBundleSellingMagnitude;
|
|
48
|
+
exports.getBundleSignedUnit = getBundleSignedUnit;
|
|
49
|
+
exports.getOrderProductLineUid = getOrderProductLineUid;
|
|
50
|
+
exports.getProductSkuOptions = getProductSkuOptions;
|
|
51
|
+
exports.getRuntimeProductOrigin = getRuntimeProductOrigin;
|
|
52
|
+
exports.hasAssignedHolderId = hasAssignedHolderId;
|
|
53
|
+
exports.indexOrderProductsByUid = indexOrderProductsByUid;
|
|
54
|
+
exports.isEmptyOrderProductDisplayValue = isEmptyOrderProductDisplayValue;
|
|
55
|
+
exports.isHolderConfigRequired = isHolderConfigRequired;
|
|
56
|
+
exports.isMarkdownBundle = isMarkdownBundle;
|
|
57
|
+
exports.isTempOrder = isTempOrder;
|
|
58
|
+
exports.mapPaymentItemToOrderPayment = mapPaymentItemToOrderPayment;
|
|
59
|
+
exports.mapPaymentItemsToOrderPayments = mapPaymentItemsToOrderPayments;
|
|
60
|
+
Object.defineProperty(exports, "mergeManualProductDiscountIntoList", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _manualProductDiscount.mergeManualProductDiscountIntoList;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
exports.mergeOrderProductDisplayFields = mergeOrderProductDisplayFields;
|
|
67
|
+
exports.mergeRelationForms = void 0;
|
|
68
|
+
exports.normalizeBookingIsAll = normalizeBookingIsAll;
|
|
69
|
+
exports.normalizeBookingSubType = normalizeBookingSubType;
|
|
70
|
+
exports.normalizeOrderProductDiscountList = normalizeOrderProductDiscountList;
|
|
71
|
+
exports.normalizeProductSkuOptions = normalizeProductSkuOptions;
|
|
72
|
+
exports.normalizeSubmitBooking = normalizeSubmitBooking;
|
|
73
|
+
exports.normalizeSubmitCollectPaxValue = normalizeSubmitCollectPaxValue;
|
|
74
|
+
exports.productRequiresFormSubject = productRequiresFormSubject;
|
|
75
|
+
exports.resolveEffectivePerUnitDiscount = resolveEffectivePerUnitDiscount;
|
|
76
|
+
exports.resolveIsFormSubject = resolveIsFormSubject;
|
|
77
|
+
Object.defineProperty(exports, "resolveManualDiscountMessage", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function () {
|
|
80
|
+
return _manualProductDiscount.resolveManualDiscountMessage;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(exports, "resolveManualDiscountOriginTotal", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
get: function () {
|
|
86
|
+
return _manualProductDiscount.resolveManualDiscountOriginTotal;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "resolveManualDiscountReasonFromSources", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function () {
|
|
92
|
+
return _manualProductDiscount.resolveManualDiscountReasonFromSources;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
exports.resolveManualOverrideLineOriginalPrice = resolveManualOverrideLineOriginalPrice;
|
|
96
|
+
exports.resolveRulesManualDiscountFlag = resolveRulesManualDiscountFlag;
|
|
97
|
+
Object.defineProperty(exports, "resolveSafeProductNum", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
get: function () {
|
|
100
|
+
return _manualProductDiscount.resolveSafeProductNum;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
exports.resolveSubmitCollectPax = resolveSubmitCollectPax;
|
|
104
|
+
Object.defineProperty(exports, "shouldBuildManualProductDiscount", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: function () {
|
|
107
|
+
return _manualProductDiscount.shouldBuildManualProductDiscount;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
Object.defineProperty(exports, "stripManualProductDiscountItems", {
|
|
111
|
+
enumerable: true,
|
|
112
|
+
get: function () {
|
|
113
|
+
return _manualProductDiscount.stripManualProductDiscountItems;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
exports.sumOptionUnitPrice = sumOptionUnitPrice;
|
|
117
|
+
Object.defineProperty(exports, "syncManualProductDiscountProductNum", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function () {
|
|
120
|
+
return _manualProductDiscount.syncManualProductDiscountProductNum;
|
|
16
121
|
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
|
-
// src/modules/Order/utils.ts
|
|
30
|
-
var utils_exports = {};
|
|
31
|
-
__export(utils_exports, {
|
|
32
|
-
buildSubmitPayload: () => buildSubmitPayload,
|
|
33
|
-
composeLinePrice: () => composeLinePrice,
|
|
34
|
-
createDefaultOrderRulesHooks: () => createDefaultOrderRulesHooks,
|
|
35
|
-
createDefaultTempOrder: () => createDefaultTempOrder,
|
|
36
|
-
createEmptySummary: () => import_utils3.createEmptySummary,
|
|
37
|
-
createUuidV4: () => createUuidV4,
|
|
38
|
-
ensureCartItemOriginHolder: () => ensureCartItemOriginHolder,
|
|
39
|
-
filterProductsForScanOrderMore: () => filterProductsForScanOrderMore,
|
|
40
|
-
formatDateTime: () => formatDateTime,
|
|
41
|
-
formatV1Product: () => formatV1Product,
|
|
42
|
-
generateDuration: () => generateDuration,
|
|
43
|
-
getAllDiscountList: () => getAllDiscountList,
|
|
44
|
-
isTempOrder: () => isTempOrder,
|
|
45
|
-
mergeRelationForms: () => mergeRelationForms,
|
|
46
|
-
normalizeSubmitBooking: () => normalizeSubmitBooking,
|
|
47
|
-
normalizeSubmitCollectPaxValue: () => normalizeSubmitCollectPaxValue,
|
|
48
|
-
resolveSubmitCollectPax: () => resolveSubmitCollectPax,
|
|
49
|
-
sumOptionUnitPrice: () => sumOptionUnitPrice
|
|
50
122
|
});
|
|
51
|
-
|
|
52
|
-
var
|
|
53
|
-
var
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
var
|
|
123
|
+
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
124
|
+
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
125
|
+
var _utils = require("../Holder/utils");
|
|
126
|
+
var _utils2 = require("../../solution/ScanOrder/utils");
|
|
127
|
+
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
128
|
+
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
129
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
130
|
+
/**
|
|
131
|
+
* 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
|
|
132
|
+
*
|
|
133
|
+
* 新语义 v2 约定:
|
|
134
|
+
* - `mainPrice` 必须是**已经包含 option 的主商品单价**(即 `metadata.main_product_selling_price`
|
|
135
|
+
* 或 `metadata.main_product_original_price`),option 价格不由本函数叠加。
|
|
136
|
+
* - 套餐价:Σ((bundle.bundle_selling_price ?? bundle.price) × (bundle.num ?? bundle.quantity ?? 1))
|
|
137
|
+
* 当 `useOriginalBundle=true` 时,改用 `bundle.original_price ?? bundle.product_price ?? bundle.price`。
|
|
138
|
+
* - 返回值:保留 2 位小数的字符串,方便直接写回 `selling_price` / `original_price` 字段。
|
|
139
|
+
*
|
|
140
|
+
* 被 `normalizeOrderProduct`、Rules setProduct 钩子、各 Solution 的 setDiscountSelected 共用,
|
|
141
|
+
* 保证合成逻辑单点来源。
|
|
142
|
+
*/
|
|
57
143
|
function composeLinePrice(params) {
|
|
58
|
-
const {
|
|
59
|
-
|
|
144
|
+
const {
|
|
145
|
+
mainPrice,
|
|
146
|
+
bundle,
|
|
147
|
+
useOriginalBundle
|
|
148
|
+
} = params;
|
|
149
|
+
let total = new _decimal.default(Number(mainPrice) || 0);
|
|
60
150
|
if (Array.isArray(bundle)) {
|
|
61
151
|
for (const item of bundle) {
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
152
|
+
// markdown(减价)按带符号净额取减;markup/原价维持相加。
|
|
153
|
+
const signedUnit = getBundleSignedUnit(item, {
|
|
154
|
+
useOriginal: useOriginalBundle
|
|
155
|
+
});
|
|
156
|
+
const rawNum = item?.num ?? item?.quantity ?? 1;
|
|
157
|
+
const num = new _decimal.default(Number(rawNum) || 0);
|
|
158
|
+
total = total.plus(signedUnit.times(num));
|
|
67
159
|
}
|
|
68
160
|
}
|
|
69
161
|
return total.toDecimalPlaces(2).toFixed(2);
|
|
70
162
|
}
|
|
163
|
+
function normalizeProductSkuOptions(options) {
|
|
164
|
+
if (!Array.isArray(options)) return [];
|
|
165
|
+
return options.map(option => {
|
|
166
|
+
const normalized = {
|
|
167
|
+
...(option && typeof option === 'object' ? option : {})
|
|
168
|
+
};
|
|
169
|
+
const addPrice = normalized.add_price ?? normalized.price;
|
|
170
|
+
if (addPrice !== undefined) normalized.add_price = addPrice;
|
|
171
|
+
delete normalized.price;
|
|
172
|
+
return normalized;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function ensureProductSku(product) {
|
|
176
|
+
const rawSku = product?.product_sku && typeof product.product_sku === 'object' ? product.product_sku : {};
|
|
177
|
+
return {
|
|
178
|
+
...rawSku,
|
|
179
|
+
option: normalizeProductSkuOptions(rawSku.option)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function getProductSkuOptions(product) {
|
|
183
|
+
return ensureProductSku(product).option;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 计算 option 单价合计:Σ(option.add_price × option.num)。
|
|
188
|
+
* 兼容入参仍带旧 `price` 的调用方,但运行时归一化后只维护 `add_price`。
|
|
189
|
+
* 在新语义 v2 下,main_product_original_price = source_product_price + 本函数结果。
|
|
190
|
+
*/
|
|
71
191
|
function sumOptionUnitPrice(options) {
|
|
72
|
-
let total = new
|
|
73
|
-
if (!Array.isArray(options))
|
|
74
|
-
return total;
|
|
192
|
+
let total = new _decimal.default(0);
|
|
193
|
+
if (!Array.isArray(options)) return total;
|
|
75
194
|
for (const opt of options) {
|
|
76
|
-
const price = new
|
|
77
|
-
const num = new
|
|
195
|
+
const price = new _decimal.default(Number(opt?.add_price ?? opt?.price) || 0);
|
|
196
|
+
const num = new _decimal.default(Number(opt?.num) || 0);
|
|
78
197
|
total = total.plus(price.times(num));
|
|
79
198
|
}
|
|
80
199
|
return total;
|
|
81
200
|
}
|
|
201
|
+
function getSafeOrderProductNum(num) {
|
|
202
|
+
const parsedNum = Number(num ?? 1);
|
|
203
|
+
if (!Number.isFinite(parsedNum) || parsedNum < 1) return 1;
|
|
204
|
+
return Math.floor(parsedNum);
|
|
205
|
+
}
|
|
206
|
+
function getOrderProductDepositUnitTotal(product) {
|
|
207
|
+
const metadata = product.metadata || {};
|
|
208
|
+
const paymentPrice = metadata.main_product_attached_bundle_payment_price;
|
|
209
|
+
const mainSellingPrice = metadata.main_product_selling_price;
|
|
210
|
+
const fallbackPrice = product.selling_price;
|
|
211
|
+
return new _decimal.default(Number(paymentPrice ?? mainSellingPrice ?? fallbackPrice) || 0);
|
|
212
|
+
}
|
|
213
|
+
function normalizeDepositProtocols(protocols) {
|
|
214
|
+
if (!Array.isArray(protocols)) return [];
|
|
215
|
+
return protocols.reduce((result, protocol) => {
|
|
216
|
+
const id = Number(protocol?.id);
|
|
217
|
+
if (!Number.isFinite(id)) return result;
|
|
218
|
+
result.push({
|
|
219
|
+
id: Math.floor(id),
|
|
220
|
+
title: String(protocol?.title || '')
|
|
221
|
+
});
|
|
222
|
+
return result;
|
|
223
|
+
}, []);
|
|
224
|
+
}
|
|
225
|
+
function getDepositPolicyIds(depositData) {
|
|
226
|
+
const ids = [...(Array.isArray(depositData?.self_deposit_policy_ids) ? depositData.self_deposit_policy_ids : []), ...(Array.isArray(depositData?.deposit_policy_ids) ? depositData.deposit_policy_ids : [])];
|
|
227
|
+
return ids.reduce((result, id) => {
|
|
228
|
+
const normalizedId = Number(id);
|
|
229
|
+
if (!Number.isFinite(normalizedId)) return result;
|
|
230
|
+
result.push(Math.floor(normalizedId));
|
|
231
|
+
return result;
|
|
232
|
+
}, []);
|
|
233
|
+
}
|
|
234
|
+
function handleOrderProductDeposit(params) {
|
|
235
|
+
const {
|
|
236
|
+
depositData,
|
|
237
|
+
total,
|
|
238
|
+
num
|
|
239
|
+
} = params;
|
|
240
|
+
if (!depositData) return {
|
|
241
|
+
result: false,
|
|
242
|
+
depositTotal: new _decimal.default(0)
|
|
243
|
+
};
|
|
244
|
+
const {
|
|
245
|
+
deposit_fixed,
|
|
246
|
+
deposit_percentage
|
|
247
|
+
} = depositData;
|
|
248
|
+
if (typeof deposit_fixed !== 'string' || typeof deposit_percentage !== 'string') {
|
|
249
|
+
return {
|
|
250
|
+
result: false,
|
|
251
|
+
depositTotal: new _decimal.default(0)
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
const depositFixed = new _decimal.default(deposit_fixed || 0);
|
|
255
|
+
const depositPercent = new _decimal.default(deposit_percentage || 0);
|
|
256
|
+
const productTotalPrice = new _decimal.default(total || 0);
|
|
257
|
+
const deposit = depositFixed.plus(depositPercent.times(productTotalPrice));
|
|
258
|
+
return {
|
|
259
|
+
depositTotal: deposit.times(num),
|
|
260
|
+
result: true
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function resolveOrderProductDepositSource(product, runtimeOrigin) {
|
|
264
|
+
const record = product;
|
|
265
|
+
const origin = record._origin || runtimeOrigin || {};
|
|
266
|
+
const originProduct = origin.product || {};
|
|
267
|
+
return {
|
|
268
|
+
...originProduct,
|
|
269
|
+
...origin,
|
|
270
|
+
...record,
|
|
271
|
+
custom_deposit_data: record.custom_deposit_data ?? origin.custom_deposit_data ?? originProduct.custom_deposit_data,
|
|
272
|
+
variant: record.variant ?? origin.variant ?? originProduct.variant
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function getOrderProductDeposit(product, runtimeOrigin) {
|
|
276
|
+
const depositProduct = resolveOrderProductDepositSource(product, runtimeOrigin);
|
|
277
|
+
const depositData = depositProduct.custom_deposit_data;
|
|
278
|
+
if (depositData?.has_deposit != 1) return null;
|
|
279
|
+
const num = getSafeOrderProductNum(product.num);
|
|
280
|
+
const total = getOrderProductDepositUnitTotal(product).times(num);
|
|
281
|
+
const allProtocols = normalizeDepositProtocols(depositData.deposit_policy_data);
|
|
282
|
+
const protocolIds = [];
|
|
283
|
+
let depositTotal = new _decimal.default(0);
|
|
284
|
+
let hasDeposit = false;
|
|
285
|
+
if (typeof depositData.deposit_fixed === 'string' && typeof depositData.deposit_percentage === 'string') {
|
|
286
|
+
const result = handleOrderProductDeposit({
|
|
287
|
+
depositData,
|
|
288
|
+
total,
|
|
289
|
+
num
|
|
290
|
+
});
|
|
291
|
+
if (result.result) {
|
|
292
|
+
depositTotal = result.depositTotal;
|
|
293
|
+
protocolIds.push(...getDepositPolicyIds({
|
|
294
|
+
self_deposit_policy_ids: depositData.self_deposit_policy_ids
|
|
295
|
+
}));
|
|
296
|
+
hasDeposit = true;
|
|
297
|
+
}
|
|
298
|
+
} else {
|
|
299
|
+
const productVariantId = depositProduct.product_variant_id ?? product.product_variant_id;
|
|
300
|
+
if (productVariantId) {
|
|
301
|
+
const variantProduct = (depositProduct.variant || []).find(item => item?.id === productVariantId);
|
|
302
|
+
const variantDepositData = variantProduct?.custom_deposit_data;
|
|
303
|
+
const result = handleOrderProductDeposit({
|
|
304
|
+
depositData: variantDepositData,
|
|
305
|
+
total,
|
|
306
|
+
num
|
|
307
|
+
});
|
|
308
|
+
if (result.result) {
|
|
309
|
+
depositTotal = result.depositTotal;
|
|
310
|
+
protocolIds.push(...getDepositPolicyIds({
|
|
311
|
+
self_deposit_policy_ids: variantDepositData?.self_deposit_policy_ids
|
|
312
|
+
}));
|
|
313
|
+
hasDeposit = true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (Array.isArray(product.product_bundle) && product.product_bundle.length) {
|
|
317
|
+
depositTotal = product.product_bundle.reduce((accumulator, bundleProduct) => {
|
|
318
|
+
const bundleDepositData = bundleProduct?.custom_deposit_data;
|
|
319
|
+
const result = handleOrderProductDeposit({
|
|
320
|
+
depositData: bundleDepositData,
|
|
321
|
+
total: bundleProduct?.price,
|
|
322
|
+
num: getSafeOrderProductNum(bundleProduct?.num || 1)
|
|
323
|
+
});
|
|
324
|
+
if (!result.result) return accumulator;
|
|
325
|
+
protocolIds.push(...getDepositPolicyIds({
|
|
326
|
+
self_deposit_policy_ids: bundleDepositData?.self_deposit_policy_ids
|
|
327
|
+
}));
|
|
328
|
+
hasDeposit = true;
|
|
329
|
+
return accumulator.plus(result.depositTotal);
|
|
330
|
+
}, new _decimal.default(0));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (!hasDeposit) return null;
|
|
334
|
+
const protocolIdSet = new Set(protocolIds);
|
|
335
|
+
const protocols = allProtocols.filter(protocol => protocolIdSet.has(protocol.id));
|
|
336
|
+
return {
|
|
337
|
+
total: depositTotal.toNumber(),
|
|
338
|
+
protocols
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* 仅基于 tempOrder.products 重算整单定金。
|
|
344
|
+
*
|
|
345
|
+
* 商品折扣在进入定金计算前已体现在商品行价格字段中,
|
|
346
|
+
* 因此这里只按商品定金规则汇总,不再扣减 discount_list;tempOrder.bookings 不参与这里的计算。
|
|
347
|
+
*/
|
|
348
|
+
function calculateOrderProductsDeposit(products = [], options) {
|
|
349
|
+
const protocolMap = new Map();
|
|
350
|
+
let total = new _decimal.default(0);
|
|
351
|
+
let hasDeposit = false;
|
|
352
|
+
for (const product of products || []) {
|
|
353
|
+
const productUid = product.metadata?.unique_identification_number;
|
|
354
|
+
const runtimeOrigin = productUid ? options?.productsByUid?.[productUid]?.origin : undefined;
|
|
355
|
+
const deposit = getOrderProductDeposit(product, runtimeOrigin);
|
|
356
|
+
product.deposit = deposit;
|
|
357
|
+
if (!deposit?.total || Number(deposit.total) <= 0) continue;
|
|
358
|
+
total = total.plus(deposit.total);
|
|
359
|
+
for (const protocol of deposit.protocols || []) {
|
|
360
|
+
if (!protocolMap.has(protocol.id)) protocolMap.set(protocol.id, protocol);
|
|
361
|
+
}
|
|
362
|
+
hasDeposit = true;
|
|
363
|
+
}
|
|
364
|
+
const roundedTotal = total.toDecimalPlaces(2, _decimal.default.ROUND_HALF_UP);
|
|
365
|
+
const protocols = [...protocolMap.values()];
|
|
366
|
+
return {
|
|
367
|
+
total: roundedTotal.toNumber(),
|
|
368
|
+
totalText: roundedTotal.toFixed(2),
|
|
369
|
+
protocols,
|
|
370
|
+
deposit_policy_ids: protocols.map(protocol => protocol.id),
|
|
371
|
+
hasDeposit
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* 判定套餐子商品是否为 markdown(减价)类型。
|
|
377
|
+
* 与后端口径一致:price_type='markdown' 且 price_type_ext 非 'product_price'(原价子商品)。
|
|
378
|
+
*/
|
|
379
|
+
function isMarkdownBundle(bundle) {
|
|
380
|
+
if (!bundle || typeof bundle !== 'object') return false;
|
|
381
|
+
const ext = bundle.price_type_ext ?? bundle.custom_price_type_ext;
|
|
382
|
+
const type = bundle.price_type ?? bundle.custom_price_type;
|
|
383
|
+
return type === 'markdown' && ext !== 'product_price';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* 套餐子商品对「行价」的带符号单位贡献(与后端 markdown 口径对齐)。
|
|
388
|
+
*
|
|
389
|
+
* - markdown(减价):净额 = |catalog 毛价| − Σ(option.add_price×num),**取负**(行内减)。
|
|
390
|
+
* catalog 毛价优先 `price`/`custom_price`(避免读已落净额的 `bundle_selling_price` 造成 option 二次扣减);
|
|
391
|
+
* 仅当毛价缺失(历史/hydrate 仅剩净额)时退回 `bundle_selling_price`,且此时不再扣 option。
|
|
392
|
+
* - markup(加价)/原价子商品:维持 `+(bundle_selling_price ?? price)`,行为不变。
|
|
393
|
+
*/
|
|
394
|
+
function getBundleSignedUnit(bundle, options) {
|
|
395
|
+
if (!bundle || typeof bundle !== 'object') return new _decimal.default(0);
|
|
396
|
+
const useOriginal = options?.useOriginal ?? false;
|
|
397
|
+
if (isMarkdownBundle(bundle)) {
|
|
398
|
+
const catalog = useOriginal ? bundle.original_price ?? bundle.product_price ?? bundle.custom_price ?? bundle.base_price ?? bundle.price : bundle.custom_price ?? bundle.product_price ?? bundle.original_price ?? bundle.base_price ?? bundle.price;
|
|
399
|
+
if (catalog !== undefined && catalog !== null && catalog !== '') {
|
|
400
|
+
const raw = new _decimal.default(Number(catalog) || 0);
|
|
401
|
+
// 负值表示价格已是「带符号净额」(如 cart/changePrice 产出的 -3.7),直接取用不再扣 option,
|
|
402
|
+
// 避免与下游 option 二次扣减;正值为毛价(H5 路径,如 5),净额 = price − Σoptions 后取负。
|
|
403
|
+
if (raw.lt(0)) return raw;
|
|
404
|
+
return raw.minus(sumOptionUnitPrice(bundle.option)).negated();
|
|
405
|
+
}
|
|
406
|
+
// 仅剩净额(无毛价)兜底:直接取负,不再扣 option
|
|
407
|
+
return new _decimal.default(Number(bundle.bundle_selling_price) || 0).abs().negated();
|
|
408
|
+
}
|
|
409
|
+
const rawPrice = useOriginal ? bundle.original_price ?? bundle.product_price ?? bundle.price : bundle.bundle_selling_price ?? bundle.price;
|
|
410
|
+
return new _decimal.default(Number(rawPrice) || 0);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* 套餐子商品 `bundle_selling_price` 的存储净额(正值幅度)。
|
|
415
|
+
* markdown 取净额绝对值(3.70);markup/原价维持原值。
|
|
416
|
+
*/
|
|
417
|
+
function getBundleSellingMagnitude(bundle) {
|
|
418
|
+
return getBundleSignedUnit(bundle).abs();
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* OrderModule 默认 Rules 钩子工厂。
|
|
423
|
+
*
|
|
424
|
+
* 价格语义约定(订单域,v2 composite 口径):
|
|
425
|
+
* - `selling_price`:券后 **行 composite 单价**
|
|
426
|
+
* = `metadata.main_product_selling_price` + Σ(bundle_selling_price × num)。
|
|
427
|
+
* - `original_price`:券前 **行 composite 单价**
|
|
428
|
+
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
429
|
+
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
430
|
+
* 不含折扣。**权威源**。
|
|
431
|
+
* - `metadata.main_product_original_price` = source + Σ(option.price × option.num)(含 option、不含折扣)。
|
|
432
|
+
* - `metadata.main_product_selling_price` = main_original − 主商品券 per-unit amount(含 option、含折扣)。
|
|
433
|
+
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
434
|
+
*
|
|
435
|
+
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
436
|
+
* - `getProduct.price` / `getProduct.original_price` 回传 **source-level 主价**
|
|
437
|
+
* (`metadata.source_product_price`)。Rules 内部 `getProductTotalPrice` /
|
|
438
|
+
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
439
|
+
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
440
|
+
* total(source + option + bundle)对齐。
|
|
441
|
+
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
442
|
+
* 加回 Σoptions,重新合成含 option 的 main_product_* 并派生 composite。
|
|
443
|
+
* 优先级:
|
|
444
|
+
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
445
|
+
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
446
|
+
* 3. `values.total / num`(仅当 Rules 只给出总价时的兜底)
|
|
447
|
+
*
|
|
448
|
+
* 导出为纯函数方便单测直接驱动钩子,不依赖 OrderModule 实例。
|
|
449
|
+
*/
|
|
450
|
+
|
|
451
|
+
/** Rules calcDiscount 用手动价标记;undefined 表示交给 Rules 用 total/origin_total 推断 */
|
|
452
|
+
function resolveRulesManualDiscountFlag(metadata) {
|
|
453
|
+
if (!metadata) return undefined;
|
|
454
|
+
if (metadata.is_manual_discount === true || metadata.is_manual_discount === 1) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
const priceOverride = metadata.price_override;
|
|
458
|
+
if (priceOverride !== undefined && priceOverride !== null && priceOverride !== '') {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
return undefined;
|
|
462
|
+
}
|
|
463
|
+
function normalizeOrderProductDiscountAmount(amount) {
|
|
464
|
+
if (amount === undefined || amount === null) return undefined;
|
|
465
|
+
return String(amount);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* 商品行折扣只保留后端 OrderProductDiscountItem 协议字段。
|
|
470
|
+
* Rules/券计算过程中的 `_num`、`config` 等运行态字段不应进入 tempOrder 或提交 payload。
|
|
471
|
+
*/
|
|
472
|
+
function normalizeOrderProductDiscountList(discountList) {
|
|
473
|
+
if (!Array.isArray(discountList)) return [];
|
|
474
|
+
return discountList.filter(item => !!item && typeof item === 'object').map(item => {
|
|
475
|
+
const normalized = {
|
|
476
|
+
discount_id: Number.isFinite(Number(item.discount_id)) ? Number(item.discount_id) : 0
|
|
477
|
+
};
|
|
478
|
+
if (item.order_discount_id === null) {
|
|
479
|
+
normalized.order_discount_id = null;
|
|
480
|
+
} else if (item.order_discount_id !== undefined) {
|
|
481
|
+
const orderDiscountId = Number(item.order_discount_id);
|
|
482
|
+
if (Number.isFinite(orderDiscountId)) {
|
|
483
|
+
normalized.order_discount_id = orderDiscountId;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (item.type !== undefined) normalized.type = item.type;
|
|
487
|
+
const amount = normalizeOrderProductDiscountAmount(item.amount);
|
|
488
|
+
if (amount !== undefined) normalized.amount = amount;
|
|
489
|
+
if (item.discount && typeof item.discount === 'object') {
|
|
490
|
+
normalized.discount = {
|
|
491
|
+
...item.discount
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (item.metadata === null) {
|
|
495
|
+
normalized.metadata = null;
|
|
496
|
+
} else if (item.metadata && typeof item.metadata === 'object') {
|
|
497
|
+
normalized.metadata = {
|
|
498
|
+
...item.metadata
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return normalized;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
function resolveSubmitBundleMapId(bundle) {
|
|
505
|
+
const metadataMapId = bundle.metadata?.custom_product_bundle_map_id;
|
|
506
|
+
if (metadataMapId !== undefined && metadataMapId !== null && metadataMapId !== '') {
|
|
507
|
+
return metadataMapId;
|
|
508
|
+
}
|
|
509
|
+
if (bundle._id !== undefined && bundle._id !== null && bundle._id !== '') {
|
|
510
|
+
return bundle._id;
|
|
511
|
+
}
|
|
512
|
+
return undefined;
|
|
513
|
+
}
|
|
514
|
+
function collectSubmitProductDiscountList(product) {
|
|
515
|
+
const submitDiscountList = Array.isArray(product?.discount_list) ? [...product.discount_list] : [];
|
|
516
|
+
for (const bundle of product?.product_bundle || []) {
|
|
517
|
+
if (!bundle || typeof bundle !== 'object') continue;
|
|
518
|
+
const bundleMapId = resolveSubmitBundleMapId(bundle);
|
|
519
|
+
const bundleDiscountList = Array.isArray(bundle.discount_list) ? bundle.discount_list : [];
|
|
520
|
+
for (const discount of bundleDiscountList) {
|
|
521
|
+
if (!discount || typeof discount !== 'object') continue;
|
|
522
|
+
const discountMetadata = discount.metadata && typeof discount.metadata === 'object' ? discount.metadata : {};
|
|
523
|
+
const discountMapId = discountMetadata.custom_product_bundle_map_id !== undefined && discountMetadata.custom_product_bundle_map_id !== null && discountMetadata.custom_product_bundle_map_id !== '' ? discountMetadata.custom_product_bundle_map_id : bundleMapId;
|
|
524
|
+
submitDiscountList.push({
|
|
525
|
+
...discount,
|
|
526
|
+
...(discountMapId !== undefined ? {
|
|
527
|
+
metadata: {
|
|
528
|
+
...discountMetadata,
|
|
529
|
+
custom_product_bundle_map_id: discountMapId
|
|
530
|
+
}
|
|
531
|
+
} : {})
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return normalizeOrderProductDiscountList(submitDiscountList);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* 手动改价(price_override)时行级 original_price(composite 单价):
|
|
540
|
+
* 购物车划线价应对齐 metadata.origin._extend.origin_total(改价前单价 composite,如 40),
|
|
541
|
+
* 而非 bundle 子项 catalog 原价合成的 composedOriginalPrice(如 30)。
|
|
542
|
+
*
|
|
543
|
+
* origin_total 与 SkuDetailModal / cacheItem._extend 一致,为单价语义,不再除以 num。
|
|
544
|
+
*/
|
|
545
|
+
function resolveManualOverrideLineOriginalPrice(params, fallbackCompositeOriginal) {
|
|
546
|
+
const metadata = params.metadata || {};
|
|
547
|
+
const priceOverride = metadata.price_override;
|
|
548
|
+
if (priceOverride === undefined || priceOverride === null || priceOverride === '') {
|
|
549
|
+
return fallbackCompositeOriginal;
|
|
550
|
+
}
|
|
551
|
+
const refTotal = metadata.origin?._extend?.origin_total;
|
|
552
|
+
if (refTotal !== undefined && refTotal !== null && refTotal !== '') {
|
|
553
|
+
const parsed = Number(refTotal);
|
|
554
|
+
if (Number.isFinite(parsed)) {
|
|
555
|
+
return new _decimal.default(parsed).toDecimalPlaces(2).toFixed(2);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
const lineOriginal = params.lineOriginalPrice;
|
|
559
|
+
if (lineOriginal !== undefined && lineOriginal !== null && lineOriginal !== '') {
|
|
560
|
+
const parsedLine = Number(lineOriginal);
|
|
561
|
+
const parsedFallback = Number(fallbackCompositeOriginal);
|
|
562
|
+
if (Number.isFinite(parsedLine) && Number.isFinite(parsedFallback) && parsedLine > parsedFallback) {
|
|
563
|
+
return new _decimal.default(parsedLine).toDecimalPlaces(2).toFixed(2);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return fallbackCompositeOriginal;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* 计算商品行「每单位有效折扣」:discount_list 合计 + 被 Rules 剥离但仍 inPromotion 的差额。
|
|
571
|
+
*
|
|
572
|
+
* Rules.calcDiscount 会把 type=promotion 从 discount_list 去掉,但 metadata._promotion 仍保留;
|
|
573
|
+
* applyProductDiscountPrices 必须回读 _promotion,否则抬价/降价都会在第二步被 source 原价覆盖。
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* resolveEffectivePerUnitDiscount({ metadata: { _promotion: { inPromotion: true, originalPrice: 1, finalPrice: 5 } }, discount_list: [] });
|
|
577
|
+
* // => -4
|
|
578
|
+
*/
|
|
579
|
+
function resolveEffectivePerUnitDiscount(product) {
|
|
580
|
+
const discountList = Array.isArray(product?.discount_list) ? product.discount_list : [];
|
|
581
|
+
const fromList = discountList.reduce((sum, discount) => sum + Number(discount?.amount || 0), 0);
|
|
582
|
+
const hasPromoDiscountItem = discountList.some(item => item?.type === 'promotion');
|
|
583
|
+
if (hasPromoDiscountItem) return fromList;
|
|
584
|
+
const metadata = product?.metadata || {};
|
|
585
|
+
const promo = metadata._promotion;
|
|
586
|
+
if (promo?.inPromotion !== true) return fromList;
|
|
587
|
+
const optionSum = sumOptionUnitPrice(getProductSkuOptions(product)).toNumber();
|
|
588
|
+
|
|
589
|
+
// applyPromotion 写价后、Rules 剥离 promotion discount 的兜底
|
|
590
|
+
if (!discountList.length && metadata.source_product_price != null && metadata.main_product_selling_price != null) {
|
|
591
|
+
const source = Number(metadata.source_product_price);
|
|
592
|
+
const selling = Number(metadata.main_product_selling_price) - optionSum;
|
|
593
|
+
if (Number.isFinite(source) && Number.isFinite(selling) && source !== selling) {
|
|
594
|
+
return fromList + (source - selling);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
const originalPrice = Number(promo.originalPrice);
|
|
598
|
+
const finalPrice = Number(promo.finalPrice);
|
|
599
|
+
if (!Number.isFinite(originalPrice) || !Number.isFinite(finalPrice)) return fromList;
|
|
600
|
+
return fromList + (originalPrice - finalPrice);
|
|
601
|
+
}
|
|
82
602
|
function createDefaultOrderRulesHooks() {
|
|
83
603
|
const toUnitPriceString = (totalLike, num) => {
|
|
84
604
|
const effectiveNum = Number(num) > 0 ? Number(num) : 1;
|
|
85
|
-
return new
|
|
605
|
+
return new _decimal.default(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
|
|
606
|
+
};
|
|
607
|
+
const getBundleIdentity = bundle => {
|
|
608
|
+
return [bundle.bundle_id ?? bundle.id ?? '', bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? '', bundle.bundle_variant_id ?? bundle.variant_id ?? bundle.product_variant_id ?? 0, bundle.bundle_group_id ?? bundle.group_id ?? ''].join('|');
|
|
609
|
+
};
|
|
610
|
+
const mergeRulesBundlePrices = (currentBundle, rulesBundle) => {
|
|
611
|
+
if (!Array.isArray(rulesBundle)) return rulesBundle;
|
|
612
|
+
const currentByIdentity = new Map();
|
|
613
|
+
(currentBundle || []).forEach(bundle => {
|
|
614
|
+
if (!bundle || typeof bundle !== 'object') return;
|
|
615
|
+
currentByIdentity.set(getBundleIdentity(bundle), bundle);
|
|
616
|
+
});
|
|
617
|
+
return rulesBundle.map(bundle => {
|
|
618
|
+
if (!bundle || typeof bundle !== 'object') return bundle;
|
|
619
|
+
const current = currentByIdentity.get(getBundleIdentity(bundle));
|
|
620
|
+
if (!current) return bundle;
|
|
621
|
+
const bundleWithDisplayFields = {
|
|
622
|
+
...bundle,
|
|
623
|
+
...(isEmptyOrderProductDisplayValue(bundle.cover) && !isEmptyOrderProductDisplayValue(current.cover) ? {
|
|
624
|
+
cover: current.cover
|
|
625
|
+
} : {})
|
|
626
|
+
};
|
|
627
|
+
const isProductPriceBundle = (bundle.price_type_ext ?? current.price_type_ext) === 'product_price';
|
|
628
|
+
if (!isProductPriceBundle) return bundleWithDisplayFields;
|
|
629
|
+
const sourcePrice = current.price ?? current.custom_price ?? current.original_price ?? current.bundle_selling_price;
|
|
630
|
+
const originalPrice = current.original_price ?? current.product_price ?? current.price ?? current.custom_price ?? sourcePrice;
|
|
631
|
+
return {
|
|
632
|
+
...bundleWithDisplayFields,
|
|
633
|
+
...(sourcePrice !== undefined ? {
|
|
634
|
+
price: sourcePrice
|
|
635
|
+
} : {}),
|
|
636
|
+
...(originalPrice !== undefined ? {
|
|
637
|
+
original_price: originalPrice
|
|
638
|
+
} : {}),
|
|
639
|
+
...(current.original_total !== undefined ? {
|
|
640
|
+
original_total: current.original_total
|
|
641
|
+
} : {})
|
|
642
|
+
};
|
|
643
|
+
});
|
|
86
644
|
};
|
|
87
645
|
return {
|
|
88
|
-
getProduct:
|
|
89
|
-
|
|
646
|
+
getProduct: product => {
|
|
647
|
+
// source_product_price 是权威源;兜底链:source → mainSelling − options(反推)→ 行 selling_price
|
|
90
648
|
const metadataAny = product.metadata || {};
|
|
91
|
-
const optionSum = sumOptionUnitPrice(product
|
|
649
|
+
const optionSum = sumOptionUnitPrice(getProductSkuOptions(product));
|
|
92
650
|
let sourcePrice;
|
|
93
|
-
if (metadataAny.source_product_price !==
|
|
651
|
+
if (metadataAny.source_product_price !== undefined) {
|
|
94
652
|
sourcePrice = String(metadataAny.source_product_price);
|
|
95
|
-
} else if (metadataAny.main_product_selling_price !==
|
|
96
|
-
sourcePrice = new
|
|
97
|
-
Number(metadataAny.main_product_selling_price) || 0
|
|
98
|
-
).minus(optionSum).toDecimalPlaces(2).toString();
|
|
653
|
+
} else if (metadataAny.main_product_selling_price !== undefined) {
|
|
654
|
+
sourcePrice = new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSum).toDecimalPlaces(2).toString();
|
|
99
655
|
} else {
|
|
100
656
|
sourcePrice = String(product.selling_price ?? 0);
|
|
101
657
|
}
|
|
102
658
|
let sourceOriginalPrice;
|
|
103
|
-
if (metadataAny.source_product_price !==
|
|
659
|
+
if (metadataAny.source_product_price !== undefined) {
|
|
104
660
|
sourceOriginalPrice = String(metadataAny.source_product_price);
|
|
105
|
-
} else if (metadataAny.main_product_original_price !==
|
|
106
|
-
sourceOriginalPrice = new
|
|
107
|
-
Number(metadataAny.main_product_original_price) || 0
|
|
108
|
-
).minus(optionSum).toDecimalPlaces(2).toString();
|
|
661
|
+
} else if (metadataAny.main_product_original_price !== undefined) {
|
|
662
|
+
sourceOriginalPrice = new _decimal.default(Number(metadataAny.main_product_original_price) || 0).minus(optionSum).toDecimalPlaces(2).toString();
|
|
109
663
|
} else {
|
|
110
664
|
sourceOriginalPrice = sourcePrice;
|
|
111
665
|
}
|
|
@@ -113,43 +667,52 @@ function createDefaultOrderRulesHooks() {
|
|
|
113
667
|
id: product.product_id,
|
|
114
668
|
// Rules 引擎用 _id 作为 processedProductsMap 键;必须与购物车行级 identity 一致,
|
|
115
669
|
// 否则同 SKU 不同小料会在 calcDiscount 重组时互相覆盖。
|
|
116
|
-
// 不透明 identity 契约下,normalizeOrderProduct /
|
|
670
|
+
// 不透明 identity 契约下,normalizeOrderProduct / hydrate 已保证唯一值存在;
|
|
117
671
|
// 留 fingerprint 分支仅作 Rules 单测里直接传裸 product 时的兜底。
|
|
118
|
-
_id: product.
|
|
119
|
-
product.product_option_item,
|
|
120
|
-
product.product_bundle
|
|
121
|
-
)}`,
|
|
672
|
+
_id: product.metadata?.unique_identification_number ? `${product.product_id}_${product.product_variant_id}_${product.metadata.unique_identification_number}` : `${product.product_id}_${product.product_variant_id}_${(0, _utils2.buildProductLineFingerprint)(getProductSkuOptions(product), product.product_bundle)}`,
|
|
122
673
|
// Rules 内部 getProductTotalPrice / getProductOriginTotalPrice 会各自再叠加 bundle + option,
|
|
123
674
|
// 所以这里必须喂 source-level(不含 option、不含 bundle、不含折扣)单价,避免双加 option。
|
|
124
675
|
price: sourcePrice,
|
|
125
676
|
// total / origin_total 使用 composite × num,跟 Rules 内部产出的 total 对齐(含 option + bundle)。
|
|
126
|
-
total: new
|
|
127
|
-
origin_total: new
|
|
128
|
-
product.original_price || product.selling_price || 0
|
|
129
|
-
).times(product.num || 1).toNumber(),
|
|
677
|
+
total: new _decimal.default(product.selling_price || 0).times(product.num || 1).toNumber(),
|
|
678
|
+
origin_total: new _decimal.default(product.original_price || product.selling_price || 0).times(product.num || 1).toNumber(),
|
|
130
679
|
original_price: sourceOriginalPrice,
|
|
131
680
|
quantity: product.num || 1,
|
|
132
681
|
num: product.num || 1,
|
|
133
682
|
discount_list: product.discount_list || [],
|
|
134
683
|
bundle: product.product_bundle || [],
|
|
135
|
-
booking_id:
|
|
684
|
+
booking_id: product.metadata?.booking_id || null,
|
|
136
685
|
isClient: false,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
686
|
+
// 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
|
|
687
|
+
// 无券时会把 bundle 价还原成 original_price(手动改价套餐会从 20 回到 30)。
|
|
688
|
+
isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
|
|
689
|
+
holder_id: product.metadata?.holder_id,
|
|
690
|
+
startDate: product.metadata?.start_date || product.metadata?.startDate,
|
|
691
|
+
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSum).toDecimalPlaces(2).toString() : undefined,
|
|
692
|
+
inPromotion: metadataAny._promotion?.inPromotion === true,
|
|
693
|
+
_promotion: metadataAny._promotion
|
|
140
694
|
};
|
|
141
695
|
},
|
|
142
696
|
setProduct: (product, values) => {
|
|
143
697
|
const nextNum = Number(values.quantity ?? product.num ?? 1) || 1;
|
|
144
698
|
const metadataAny = product.metadata || {};
|
|
145
|
-
const existedSource = metadataAny.source_product_price ?? product.selling_price ??
|
|
146
|
-
const nextOptions = product
|
|
699
|
+
const existedSource = metadataAny.source_product_price ?? product.selling_price ?? '0';
|
|
700
|
+
const nextOptions = getProductSkuOptions(product);
|
|
147
701
|
const optionSum = sumOptionUnitPrice(nextOptions);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
702
|
+
|
|
703
|
+
// Rules 返回的 main_product_selling_price / price / total 均为 source-level。
|
|
704
|
+
// 优先级:main_product_selling_price(per-unit 券后 source)> price(还原/good_pass 分支)>
|
|
705
|
+
// total/num(仅当 Rules 只给 total 时的兜底)> 保留当前 source。
|
|
706
|
+
const nextSourceSellingPrice = values.main_product_selling_price !== undefined ? String(values.main_product_selling_price) : values.price !== undefined ? String(values.price) : values.total !== undefined ? toUnitPriceString(values.total, nextNum) : String(existedSource);
|
|
707
|
+
|
|
708
|
+
// 券前 source:values.original_price 是 source-level(Rules 层本就不含 option),
|
|
709
|
+
// 缺省时保留现有 source(券前 = 当前 source)。
|
|
710
|
+
const nextSourceOriginalPrice = values.original_price !== undefined ? String(values.original_price) : String(existedSource);
|
|
711
|
+
|
|
712
|
+
// 含 option 的 main_product_*
|
|
713
|
+
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
714
|
+
const nextMainOriginalPrice = new _decimal.default(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
715
|
+
const nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
|
|
153
716
|
const composedSellingPrice = composeLinePrice({
|
|
154
717
|
mainPrice: nextMainSellingPrice,
|
|
155
718
|
bundle: nextBundle
|
|
@@ -159,10 +722,15 @@ function createDefaultOrderRulesHooks() {
|
|
|
159
722
|
bundle: nextBundle,
|
|
160
723
|
useOriginalBundle: true
|
|
161
724
|
});
|
|
725
|
+
const finalOriginalPrice = resolveManualOverrideLineOriginalPrice({
|
|
726
|
+
num: nextNum,
|
|
727
|
+
metadata: metadataAny,
|
|
728
|
+
lineOriginalPrice: product.original_price
|
|
729
|
+
}, composedOriginalPrice);
|
|
162
730
|
return {
|
|
163
731
|
...product,
|
|
164
732
|
selling_price: composedSellingPrice,
|
|
165
|
-
original_price:
|
|
733
|
+
original_price: finalOriginalPrice,
|
|
166
734
|
discount_list: values.discount_list ?? product.discount_list,
|
|
167
735
|
num: values.quantity ?? product.num,
|
|
168
736
|
product_bundle: nextBundle,
|
|
@@ -177,47 +745,73 @@ function createDefaultOrderRulesHooks() {
|
|
|
177
745
|
}
|
|
178
746
|
};
|
|
179
747
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* 通过 session 类商品的开始时间结束时间生成商品的时长
|
|
751
|
+
* @param {CartItem} cartItem
|
|
752
|
+
* @return {*}
|
|
753
|
+
*/
|
|
754
|
+
const generateDuration = cartItem => {
|
|
755
|
+
const startDate = (0, _dayjs.default)(`${cartItem.start_date} ${cartItem.start_time}`);
|
|
756
|
+
const endDate = (0, _dayjs.default)(`${cartItem.end_date} ${cartItem.end_time}`);
|
|
757
|
+
const duration = endDate.diff(startDate, 'minutes');
|
|
758
|
+
return {
|
|
759
|
+
duration,
|
|
760
|
+
durationType: 'minutes'
|
|
761
|
+
};
|
|
185
762
|
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* 合并关联表单
|
|
766
|
+
* @param relationForms 关联表单
|
|
767
|
+
* @returns 合并后的关联表单
|
|
768
|
+
*/
|
|
769
|
+
exports.generateDuration = generateDuration;
|
|
770
|
+
const mergeRelationForms = relationForms => {
|
|
771
|
+
return Object.values(relationForms.reduce((acc, cur) => {
|
|
772
|
+
const {
|
|
773
|
+
form_id,
|
|
774
|
+
form_record_ids
|
|
775
|
+
} = cur;
|
|
776
|
+
// 如果 acc 中没有 form_id,则初始化一个空数组
|
|
777
|
+
if (!acc[form_id]) {
|
|
778
|
+
acc[form_id] = {
|
|
779
|
+
form_id,
|
|
780
|
+
form_record_ids: []
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// 兼容 form_record_id 可能是数组或单个数字
|
|
785
|
+
const ids = Array.isArray(form_record_ids) ? form_record_ids : [form_record_ids];
|
|
786
|
+
// 过滤掉空值(null、undefined等)
|
|
787
|
+
const validIds = ids.filter(id => id != null);
|
|
788
|
+
acc[form_id].form_record_ids.push(...validIds);
|
|
789
|
+
// 去重
|
|
790
|
+
acc[form_id].form_record_ids = [...new Set(acc[form_id].form_record_ids)];
|
|
791
|
+
return acc;
|
|
792
|
+
}, {})).filter(item => item.form_record_ids.length > 0); // 过滤掉没有有效记录的表单
|
|
200
793
|
};
|
|
794
|
+
exports.mergeRelationForms = mergeRelationForms;
|
|
201
795
|
function getCustomerIdFromStorage(window) {
|
|
202
|
-
var _a;
|
|
203
796
|
try {
|
|
204
|
-
const customer = JSON.parse(
|
|
205
|
-
const customerId = Number(customer
|
|
206
|
-
return Number.isFinite(customerId) && customerId > 0 ? customerId :
|
|
797
|
+
const customer = JSON.parse(window?.getLocalStorage?.('customer') || '{}');
|
|
798
|
+
const customerId = Number(customer?.id);
|
|
799
|
+
return Number.isFinite(customerId) && customerId > 0 ? customerId : undefined;
|
|
207
800
|
} catch {
|
|
208
|
-
return
|
|
801
|
+
return undefined;
|
|
209
802
|
}
|
|
210
803
|
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* 为购物车行补齐订单所需的 holder 信息(与 cartAccount 结构保持一致)
|
|
807
|
+
*/
|
|
211
808
|
function ensureCartItemOriginHolder(cartItem, window) {
|
|
212
|
-
|
|
213
|
-
if ((_a = cartItem == null ? void 0 : cartItem._origin) == null ? void 0 : _a.holder) {
|
|
809
|
+
if (cartItem?._origin?.holder) {
|
|
214
810
|
return;
|
|
215
811
|
}
|
|
216
|
-
const holderConfig = (0,
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
const formRecordId = cartItem == null ? void 0 : cartItem.holder_id;
|
|
220
|
-
if (!(holderConfig == null ? void 0 : holderConfig.resource_id) || formRecordId == null) {
|
|
812
|
+
const holderConfig = (0, _utils.getProductHolderConfig)(cartItem?._productInit ?? cartItem?._productOrigin);
|
|
813
|
+
const formRecordId = cartItem?.holder_id;
|
|
814
|
+
if (!holderConfig?.resource_id || formRecordId == null) {
|
|
221
815
|
return;
|
|
222
816
|
}
|
|
223
817
|
cartItem._origin.holder = {
|
|
@@ -226,32 +820,25 @@ function ensureCartItemOriginHolder(cartItem, window) {
|
|
|
226
820
|
form_record: [formRecordId]
|
|
227
821
|
};
|
|
228
822
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
let discountList =
|
|
232
|
-
(
|
|
233
|
-
discountList = [...discountList, ...(item
|
|
234
|
-
item.discount_list =
|
|
823
|
+
;
|
|
824
|
+
const getAllDiscountList = cartItem => {
|
|
825
|
+
let discountList = cartItem?._origin?.product?.discount_list || [];
|
|
826
|
+
(cartItem?._origin?.product?.product_bundle || []).forEach(item => {
|
|
827
|
+
discountList = [...discountList, ...(item?.discount_list || [])];
|
|
828
|
+
item.discount_list = undefined;
|
|
235
829
|
});
|
|
236
830
|
return discountList;
|
|
237
831
|
};
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const randomValue = Math.floor(Math.random() * 16);
|
|
242
|
-
const value = char === "x" ? randomValue : randomValue & 3 | 8;
|
|
243
|
-
return value.toString(16);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
832
|
+
|
|
833
|
+
// ─── 以下为从 ScanOrder/utils.ts 迁入的 Order 专属工具函数 ───
|
|
834
|
+
exports.getAllDiscountList = getAllDiscountList;
|
|
246
835
|
function isTempOrder(data) {
|
|
247
|
-
if (!data || typeof data !==
|
|
248
|
-
|
|
249
|
-
if (!Array.isArray(data.products))
|
|
250
|
-
return false;
|
|
836
|
+
if (!data || typeof data !== 'object') return false;
|
|
837
|
+
if (!Array.isArray(data.products)) return false;
|
|
251
838
|
return true;
|
|
252
839
|
}
|
|
253
840
|
function formatDateTime(date) {
|
|
254
|
-
const pad =
|
|
841
|
+
const pad = value => value.toString().padStart(2, '0');
|
|
255
842
|
const year = date.getFullYear();
|
|
256
843
|
const month = pad(date.getMonth() + 1);
|
|
257
844
|
const day = pad(date.getDate());
|
|
@@ -261,61 +848,86 @@ function formatDateTime(date) {
|
|
|
261
848
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
262
849
|
}
|
|
263
850
|
function normalizeSubmitPlatform(platform) {
|
|
264
|
-
|
|
851
|
+
const value = String(platform || '').trim();
|
|
852
|
+
if (!value) return 'H5';
|
|
853
|
+
const lower = value.toLowerCase();
|
|
854
|
+
if (lower === 'pc') return 'PC';
|
|
855
|
+
if (lower === 'h5') return 'H5';
|
|
856
|
+
return value;
|
|
265
857
|
}
|
|
858
|
+
|
|
859
|
+
// 后端 checkout 协议字段 option_group_item_id;tempOrder 内部也保持同一字段名。
|
|
266
860
|
function formatSubmitOptionItems(options) {
|
|
267
|
-
if (!Array.isArray(options))
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
861
|
+
if (!Array.isArray(options)) return [];
|
|
862
|
+
return options.map(d => {
|
|
863
|
+
const option = {
|
|
864
|
+
...(d && typeof d === 'object' ? d : {}),
|
|
865
|
+
num: d?.num,
|
|
866
|
+
option_group_item_id: d?.option_group_item_id,
|
|
867
|
+
option_group_id: d?.option_group_id
|
|
868
|
+
};
|
|
869
|
+
const addPrice = d?.add_price ?? d?.price;
|
|
870
|
+
if (addPrice !== undefined) option.add_price = String(addPrice);
|
|
871
|
+
delete option.price;
|
|
872
|
+
return option;
|
|
873
|
+
});
|
|
274
874
|
}
|
|
275
875
|
function toBundleNumber(value, fallback = 0) {
|
|
276
876
|
const parsed = Number(value);
|
|
277
877
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
278
878
|
}
|
|
879
|
+
function toMoneyString(value) {
|
|
880
|
+
const parsed = Number(value);
|
|
881
|
+
if (Number.isFinite(parsed)) return parsed.toFixed(2);
|
|
882
|
+
if (value === null || value === undefined || value === '') return '0.00';
|
|
883
|
+
return String(value);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// 出站补齐:只输出后端 checkout 协议字段,运行时/详情展示字段不进入 bundle payload。
|
|
279
887
|
function formatSubmitBundleItems(bundle) {
|
|
280
|
-
if (!Array.isArray(bundle))
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
888
|
+
if (!Array.isArray(bundle)) return [];
|
|
889
|
+
return bundle.map(b => {
|
|
890
|
+
const rawBundle = b && typeof b === 'object' ? b : {};
|
|
891
|
+
const existedMetadata = rawBundle.metadata && typeof rawBundle.metadata === 'object' ? rawBundle.metadata : {};
|
|
892
|
+
const {
|
|
893
|
+
custom_product_bundle_map_id: _customProductBundleMapId,
|
|
894
|
+
...submitMetadata
|
|
895
|
+
} = existedMetadata;
|
|
896
|
+
|
|
897
|
+
// bundle_selling_price 出站存「正净额」:markdown 为 |price| − Σoptions(如 3.70),
|
|
898
|
+
// markup/原价维持原值;与后端口径一致(price 仍为毛价)。
|
|
899
|
+
const sellingPrice = getBundleSellingMagnitude(rawBundle).toFixed(2);
|
|
900
|
+
// payment 价由整单折扣均摊层产出;缺省(无折扣)时与 selling 净额同义。
|
|
901
|
+
const paymentPrice = rawBundle.bundle_payment_price !== undefined && rawBundle.bundle_payment_price !== null && rawBundle.bundle_payment_price !== '' ? toMoneyString(rawBundle.bundle_payment_price) : sellingPrice;
|
|
902
|
+
const priceValue = rawBundle.price ?? rawBundle.custom_price ?? rawBundle.bundle_selling_price;
|
|
291
903
|
const relationSurchargeIds = Array.isArray(rawBundle.relation_surcharge_ids) ? rawBundle.relation_surcharge_ids : Array.isArray(existedMetadata.relation_surcharge_ids) ? existedMetadata.relation_surcharge_ids : [];
|
|
292
|
-
const surchargeFee =
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
);
|
|
296
|
-
const
|
|
297
|
-
existedMetadata.product_discount_difference,
|
|
298
|
-
0
|
|
299
|
-
);
|
|
904
|
+
const surchargeFee = toMoneyString(rawBundle.surcharge_fee ?? existedMetadata.surcharge_fee);
|
|
905
|
+
const productDiscountDifference = toBundleNumber(existedMetadata.product_discount_difference, 0);
|
|
906
|
+
const num = toBundleNumber(rawBundle.num ?? rawBundle.quantity, 1);
|
|
907
|
+
const bundleMapId = resolveSubmitBundleMapId(rawBundle);
|
|
908
|
+
const hasSubmitBundleDiscounts = Array.isArray(rawBundle.discount_list) && rawBundle.discount_list.length > 0;
|
|
300
909
|
return {
|
|
301
|
-
...rawBundle,
|
|
302
910
|
is_charge_tax: rawBundle.is_charge_tax ?? 0,
|
|
303
|
-
tax_fee: toBundleNumber(rawBundle.tax_fee, 0),
|
|
304
911
|
bundle_variant_id: rawBundle.bundle_variant_id ?? 0,
|
|
305
|
-
num
|
|
912
|
+
num,
|
|
913
|
+
quantity: toBundleNumber(rawBundle.quantity ?? rawBundle.num, num),
|
|
306
914
|
extension_id: rawBundle.extension_id ?? 0,
|
|
307
|
-
extension_type: rawBundle.extension_type ??
|
|
308
|
-
price:
|
|
309
|
-
price_type:
|
|
310
|
-
price_type_ext: rawBundle.price_type_ext ??
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
bundle_selling_price: sellingPriceNum,
|
|
915
|
+
extension_type: rawBundle.extension_type ?? 'normal',
|
|
916
|
+
price: priceValue,
|
|
917
|
+
price_type: rawBundle.price_type ?? rawBundle.custom_price_type ?? '',
|
|
918
|
+
price_type_ext: rawBundle.price_type_ext ?? rawBundle.custom_price_type_ext ?? '',
|
|
919
|
+
bundle_selling_price: sellingPrice,
|
|
920
|
+
bundle_payment_price: paymentPrice,
|
|
314
921
|
option: formatSubmitOptionItems(rawBundle.option),
|
|
315
|
-
bundle_group_id: rawBundle
|
|
316
|
-
bundle_id: rawBundle
|
|
922
|
+
bundle_group_id: rawBundle?.bundle_group_id ?? rawBundle?.group_id,
|
|
923
|
+
bundle_id: rawBundle?.bundle_id ?? rawBundle?.id,
|
|
924
|
+
bundle_product_id: rawBundle?.bundle_product_id ?? rawBundle?._bundle_product_id,
|
|
925
|
+
cover: rawBundle.cover,
|
|
317
926
|
metadata: {
|
|
318
|
-
...
|
|
927
|
+
...submitMetadata,
|
|
928
|
+
...(hasSubmitBundleDiscounts && bundleMapId !== undefined ? {
|
|
929
|
+
custom_product_bundle_map_id: bundleMapId
|
|
930
|
+
} : {}),
|
|
319
931
|
surcharge_fee: surchargeFee,
|
|
320
932
|
relation_surcharge_ids: relationSurchargeIds,
|
|
321
933
|
product_discount_difference: productDiscountDifference
|
|
@@ -323,74 +935,118 @@ function formatSubmitBundleItems(bundle) {
|
|
|
323
935
|
};
|
|
324
936
|
});
|
|
325
937
|
}
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* 把 tempOrder product 打包成出站 submit payload。
|
|
941
|
+
*
|
|
942
|
+
* 价格字段语义(出站口径,v2 composite):
|
|
943
|
+
* - `selling_price`:**行 composite 券后单价**
|
|
944
|
+
* = `metadata.main_product_selling_price` + Σ(bundle_selling_price × num)。
|
|
945
|
+
* - `original_price`:**行 composite 券前单价**
|
|
946
|
+
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
947
|
+
* - `payment_price`:兼容后端的出站字段,行 composite 已减整单折扣均摊(无折扣时与 `selling_price` 同义)。
|
|
948
|
+
* - `metadata.source_product_price`:主商品/variant 基础价(不含 option、不含折扣),权威源。
|
|
949
|
+
* - `metadata.main_product_original_price`:含 option、不含折扣。
|
|
950
|
+
* - `metadata.main_product_selling_price`:含 option、含主商品折扣。
|
|
951
|
+
* - `metadata.price_schema_version`:schema 版本号(当前 = 2),用于跨端协商价格口径。
|
|
952
|
+
*
|
|
953
|
+
* 本函数不再改造价格字段形状,仅做字段/metadata 裁剪。
|
|
954
|
+
*/
|
|
326
955
|
function normalizeSubmitProduct(product) {
|
|
327
|
-
const {
|
|
956
|
+
const {
|
|
957
|
+
unique_identification_number: _runtimeUid,
|
|
958
|
+
...submitProduct
|
|
959
|
+
} = product;
|
|
960
|
+
const {
|
|
961
|
+
num,
|
|
962
|
+
surcharge_fee: _productSurchargeFee,
|
|
963
|
+
discount_amount: _deprecatedDiscountAmount,
|
|
964
|
+
discount_type: _deprecatedDiscountType,
|
|
965
|
+
discountway: _deprecatedDiscountway,
|
|
966
|
+
product_discount_reason: _deprecatedProductDiscountReason,
|
|
967
|
+
discount_per: _deprecatedDiscountPer,
|
|
968
|
+
...productRest
|
|
969
|
+
} = submitProduct;
|
|
970
|
+
delete productRest[`product_${'option'}_item`];
|
|
328
971
|
const rawMetadata = submitProduct.metadata || {};
|
|
329
972
|
const bookingUid = rawMetadata.booking_uid;
|
|
330
973
|
const cleanMetadata = {};
|
|
331
974
|
if (rawMetadata.unique_identification_number) {
|
|
332
975
|
cleanMetadata.unique_identification_number = rawMetadata.unique_identification_number;
|
|
333
976
|
}
|
|
334
|
-
const priceMetaKeys = [
|
|
335
|
-
"main_product_original_price",
|
|
336
|
-
"main_product_selling_price",
|
|
337
|
-
"source_product_price",
|
|
338
|
-
"price_schema_version"
|
|
339
|
-
];
|
|
977
|
+
const priceMetaKeys = ['main_product_original_price', 'main_product_selling_price', 'main_product_attached_bundle_selling_price', 'main_product_attached_bundle_payment_price', 'average_discount_amount_rate', 'source_product_price', 'main_product_attached_bundle_surcharge_fee', 'main_product_attached_bundle_tax_fee', 'surcharge_rounding_remainder', 'tax_fee_rounding_remainder', 'relation_surcharge_ids', 'discountable_flag', 'parent_unique_identification_number', 'product_add_schedule_time'];
|
|
340
978
|
for (const key of priceMetaKeys) {
|
|
341
|
-
if (rawMetadata[key] !==
|
|
979
|
+
if (rawMetadata[key] !== undefined) {
|
|
342
980
|
cleanMetadata[key] = rawMetadata[key];
|
|
343
981
|
}
|
|
344
982
|
}
|
|
983
|
+
cleanMetadata.product_discount_difference = rawMetadata.product_discount_difference ?? '';
|
|
345
984
|
if (rawMetadata.price_breakdown) {
|
|
346
985
|
cleanMetadata.price_breakdown = rawMetadata.price_breakdown;
|
|
347
986
|
}
|
|
348
|
-
if (rawMetadata.is_rule !==
|
|
987
|
+
if (rawMetadata.is_rule !== undefined) {
|
|
349
988
|
cleanMetadata.is_rule = rawMetadata.is_rule;
|
|
350
989
|
}
|
|
990
|
+
if (rawMetadata.holder_config !== undefined) {
|
|
991
|
+
cleanMetadata.holder_config = rawMetadata.holder_config;
|
|
992
|
+
}
|
|
993
|
+
const productSku = {
|
|
994
|
+
...(submitProduct.product_sku && typeof submitProduct.product_sku === 'object' ? submitProduct.product_sku : {}),
|
|
995
|
+
option: formatSubmitOptionItems(submitProduct.product_sku?.option)
|
|
996
|
+
};
|
|
351
997
|
return {
|
|
352
|
-
...
|
|
353
|
-
...bookingUid ? {
|
|
354
|
-
|
|
355
|
-
|
|
998
|
+
...productRest,
|
|
999
|
+
...(bookingUid ? {
|
|
1000
|
+
booking_uid: bookingUid
|
|
1001
|
+
} : {}),
|
|
1002
|
+
product_quantity: toBundleNumber(num ?? submitProduct.product_quantity, 1),
|
|
1003
|
+
product_sku: productSku,
|
|
1004
|
+
discount_list: collectSubmitProductDiscountList(submitProduct),
|
|
356
1005
|
product_bundle: formatSubmitBundleItems(submitProduct.product_bundle),
|
|
357
1006
|
metadata: cleanMetadata,
|
|
358
|
-
// 出站兼容:后端消费 payment_price
|
|
359
|
-
//
|
|
360
|
-
payment_price: submitProduct.selling_price
|
|
1007
|
+
// 出站兼容:后端消费 payment_price 字段(行 composite 已减整单折扣均摊)。
|
|
1008
|
+
// 由整单折扣均摊层产出;缺省(无折扣)时与 selling_price 同义。
|
|
1009
|
+
payment_price: submitProduct.payment_price ?? submitProduct.selling_price
|
|
361
1010
|
};
|
|
362
1011
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
1012
|
+
const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder'];
|
|
1013
|
+
function normalizeBookingIsAll(booking) {
|
|
1014
|
+
return booking.is_all === true || booking.is_all === 1 || booking.is_all === '1' || booking.is_all === 'true' ? 1 : 0;
|
|
1015
|
+
}
|
|
1016
|
+
function normalizeBookingSubType(booking) {
|
|
1017
|
+
if (normalizeBookingIsAll(booking) === 1) return 'days';
|
|
1018
|
+
if (booking.sub_type !== undefined && booking.sub_type !== null && booking.sub_type !== '') {
|
|
1019
|
+
return String(booking.sub_type);
|
|
1020
|
+
}
|
|
1021
|
+
return 'minutes';
|
|
1022
|
+
}
|
|
367
1023
|
function normalizeSubmitBooking(booking) {
|
|
368
1024
|
const rawMetadata = booking.metadata || {};
|
|
369
1025
|
const cleanMetadata = {};
|
|
370
1026
|
for (const key of SUBMIT_BOOKING_METADATA_WHITELIST) {
|
|
371
|
-
if (rawMetadata[key] !==
|
|
1027
|
+
if (rawMetadata[key] !== undefined) {
|
|
372
1028
|
cleanMetadata[key] = rawMetadata[key];
|
|
373
1029
|
}
|
|
374
1030
|
}
|
|
1031
|
+
if (cleanMetadata.holder_id === undefined) cleanMetadata.holder_id = null;
|
|
1032
|
+
const bookingRecord = booking;
|
|
1033
|
+
const startDate = bookingRecord.start_date;
|
|
1034
|
+
const shouldRestoreSelectDate = bookingRecord.select_date === undefined || bookingRecord.select_date === null || bookingRecord.select_date === '';
|
|
1035
|
+
const selectDateFromStartDate = typeof startDate === 'string' ? startDate.split(/\s+/)[0] : startDate;
|
|
375
1036
|
return {
|
|
376
1037
|
...booking,
|
|
1038
|
+
...(shouldRestoreSelectDate && selectDateFromStartDate ? {
|
|
1039
|
+
select_date: selectDateFromStartDate
|
|
1040
|
+
} : {}),
|
|
1041
|
+
is_all: normalizeBookingIsAll(bookingRecord),
|
|
1042
|
+
sub_type: normalizeBookingSubType(bookingRecord),
|
|
377
1043
|
metadata: cleanMetadata
|
|
378
1044
|
};
|
|
379
1045
|
}
|
|
380
|
-
|
|
1046
|
+
const DEFAULT_TABLE_OCCUPANCY_DURATION = 20;
|
|
381
1047
|
function resolveTableOccupancyDuration(tempOrder) {
|
|
382
|
-
var _a, _b, _c, _d;
|
|
383
1048
|
const metadata = tempOrder.metadata || {};
|
|
384
|
-
const candidates = [
|
|
385
|
-
metadata.table_occupancy_duration,
|
|
386
|
-
metadata.booking_duration,
|
|
387
|
-
metadata.table_duration,
|
|
388
|
-
metadata.duration,
|
|
389
|
-
(_a = metadata.table_config) == null ? void 0 : _a.occupancy_duration,
|
|
390
|
-
(_b = metadata.tableConfig) == null ? void 0 : _b.occupancy_duration,
|
|
391
|
-
(_c = metadata.resource_config) == null ? void 0 : _c.occupancy_duration,
|
|
392
|
-
(_d = metadata.resourceConfig) == null ? void 0 : _d.occupancy_duration
|
|
393
|
-
];
|
|
1049
|
+
const candidates = [metadata.table_occupancy_duration, metadata.booking_duration, metadata.table_duration, metadata.duration, metadata.table_config?.occupancy_duration, metadata.tableConfig?.occupancy_duration, metadata.resource_config?.occupancy_duration, metadata.resourceConfig?.occupancy_duration];
|
|
394
1050
|
for (const value of candidates) {
|
|
395
1051
|
const duration = Number(value);
|
|
396
1052
|
if (Number.isFinite(duration) && duration > 0) {
|
|
@@ -399,187 +1055,433 @@ function resolveTableOccupancyDuration(tempOrder) {
|
|
|
399
1055
|
}
|
|
400
1056
|
return DEFAULT_TABLE_OCCUPANCY_DURATION;
|
|
401
1057
|
}
|
|
1058
|
+
|
|
1059
|
+
/** 提交用人数:有限且为正则向下取整,否则为 1 */
|
|
402
1060
|
function normalizeSubmitCollectPaxValue(value) {
|
|
403
1061
|
const n = Number(value);
|
|
404
1062
|
return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1;
|
|
405
1063
|
}
|
|
1064
|
+
|
|
1065
|
+
/** 从临时订单 metadata 解析合成 booking 的 collect_pax */
|
|
406
1066
|
function resolveSubmitCollectPax(tempOrder) {
|
|
407
|
-
|
|
408
|
-
return normalizeSubmitCollectPaxValue((_a = tempOrder.metadata) == null ? void 0 : _a.collect_pax);
|
|
1067
|
+
return normalizeSubmitCollectPaxValue(tempOrder.metadata?.collect_pax);
|
|
409
1068
|
}
|
|
410
1069
|
function createDefaultTempOrder(params) {
|
|
411
|
-
const summary = params.summary || (0, import_utils2.createEmptySummary)();
|
|
412
1070
|
return {
|
|
413
1071
|
order_id: null,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
1072
|
+
external_sale_number: '',
|
|
1073
|
+
order_number: null,
|
|
1074
|
+
shop_order_number: null,
|
|
1075
|
+
shop_full_order_number: null,
|
|
1076
|
+
type: '',
|
|
1077
|
+
business_code: undefined,
|
|
1078
|
+
platform: 'h5',
|
|
1079
|
+
sales_channel: 'my_pisel',
|
|
1080
|
+
order_sales_channel: 'online_store',
|
|
1081
|
+
status: 'normal',
|
|
1082
|
+
payment_status: 'payment_processing',
|
|
1083
|
+
shipping_status: 'unfulfilled',
|
|
1084
|
+
customer_id: 0,
|
|
1085
|
+
customer_name: '',
|
|
1086
|
+
country_calling_code: '',
|
|
1087
|
+
phone: '',
|
|
1088
|
+
email: '',
|
|
1089
|
+
customer: null,
|
|
432
1090
|
is_price_include_tax: 1,
|
|
433
|
-
tax_title:
|
|
434
|
-
tax_country_code:
|
|
435
|
-
currency_code:
|
|
436
|
-
currency_symbol:
|
|
437
|
-
currency_format:
|
|
1091
|
+
tax_title: '',
|
|
1092
|
+
tax_country_code: '',
|
|
1093
|
+
currency_code: '',
|
|
1094
|
+
currency_symbol: '',
|
|
1095
|
+
currency_format: 'symbol_first',
|
|
438
1096
|
is_deposit: 0,
|
|
439
|
-
deposit_amount:
|
|
440
|
-
shop_discount:
|
|
441
|
-
surcharge_fee:
|
|
442
|
-
note:
|
|
1097
|
+
deposit_amount: '0.00',
|
|
1098
|
+
shop_discount: '0.00',
|
|
1099
|
+
surcharge_fee: '0.00',
|
|
1100
|
+
note: '',
|
|
443
1101
|
schedule_date: params.now,
|
|
444
|
-
created_at:
|
|
1102
|
+
created_at: undefined,
|
|
1103
|
+
request_unique_idempotency_token: '',
|
|
1104
|
+
vouchers: [],
|
|
445
1105
|
products: [],
|
|
446
1106
|
bookings: [],
|
|
447
1107
|
payments: [],
|
|
448
1108
|
surcharges: [],
|
|
449
|
-
discount_list: [],
|
|
450
1109
|
relation_forms: [],
|
|
451
1110
|
contacts: [],
|
|
452
|
-
contacts_info:
|
|
1111
|
+
contacts_info: null,
|
|
453
1112
|
holder: null,
|
|
454
|
-
|
|
455
|
-
|
|
1113
|
+
metadata: {},
|
|
1114
|
+
_extend: {
|
|
1115
|
+
productsByUid: {}
|
|
1116
|
+
}
|
|
456
1117
|
};
|
|
457
1118
|
}
|
|
458
1119
|
function buildSubmitPayload(params) {
|
|
459
1120
|
const {
|
|
460
1121
|
tempOrder,
|
|
461
1122
|
cacheId,
|
|
462
|
-
now =
|
|
1123
|
+
now = new Date(),
|
|
463
1124
|
platform,
|
|
464
1125
|
businessCode,
|
|
465
1126
|
channel,
|
|
466
1127
|
type,
|
|
1128
|
+
summary,
|
|
467
1129
|
enhance
|
|
468
1130
|
} = params;
|
|
469
1131
|
const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
|
|
470
|
-
const
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
1132
|
+
const bookingUuid = (0, _orderCollectionIdentity.createUuidV4)();
|
|
1133
|
+
const {
|
|
1134
|
+
_extend: _extend,
|
|
1135
|
+
relation_id: _relationId,
|
|
1136
|
+
table_form_id: _tableFormId,
|
|
1137
|
+
resource_id: _resourceId,
|
|
1138
|
+
summary: _summary,
|
|
1139
|
+
lastOrderInfo: _lastOrderInfo,
|
|
1140
|
+
paid_amount: _paidAmount,
|
|
1141
|
+
shop_id: _shopId,
|
|
1142
|
+
shop_note: _shopNote,
|
|
1143
|
+
shop_service_type: _shopServiceType,
|
|
1144
|
+
start_time: _startTime,
|
|
1145
|
+
customer: _customer,
|
|
1146
|
+
discount_list: _discountList,
|
|
1147
|
+
tax_fee: _rootTaxFee,
|
|
1148
|
+
total_amount: _totalAmount,
|
|
1149
|
+
total_refund_amount: _totalRefundAmount,
|
|
1150
|
+
create_date: _createDate,
|
|
1151
|
+
holder_id: _holderId,
|
|
1152
|
+
...tempOrderRest
|
|
1153
|
+
} = tempOrder;
|
|
1154
|
+
let submitType = type ?? tempOrder.type;
|
|
1155
|
+
if (!submitType) {
|
|
1156
|
+
// 如果外部没有传递 types,根据订单里当前是否有 bookings 来决定是 appointment_booking 还是 virtual
|
|
1157
|
+
if (tempOrder?.bookings?.length) {
|
|
1158
|
+
submitType = 'appointment_booking';
|
|
1159
|
+
} else {
|
|
1160
|
+
submitType = 'virtual';
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
501
1163
|
const payload = {
|
|
502
1164
|
...tempOrderRest,
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
1165
|
+
customer_id: tempOrder.customer_id ?? 1,
|
|
1166
|
+
customer_name: tempOrder.customer_name || 'Walk-In',
|
|
1167
|
+
order_number: tempOrder.order_number ?? null,
|
|
1168
|
+
shop_order_number: tempOrder.shop_order_number ?? null,
|
|
1169
|
+
shop_full_order_number: tempOrder.shop_full_order_number ?? null,
|
|
1170
|
+
platform: normalizeSubmitPlatform(platform),
|
|
1171
|
+
request_unique_idempotency_token: params?.request_unique_idempotency_token || tempOrder.request_unique_idempotency_token || `${tempOrder.external_sale_number}_${now.getTime()}`,
|
|
1172
|
+
type: submitType,
|
|
1173
|
+
business_code: businessCode ?? tempOrder.business_code,
|
|
1174
|
+
sales_channel: tempOrder.sales_channel || 'my_pisel',
|
|
1175
|
+
order_sales_channel: channel ?? tempOrder.order_sales_channel ?? 'online_store',
|
|
1176
|
+
status: tempOrder.status || 'normal',
|
|
1177
|
+
payment_status: tempOrder.payment_status || 'payment_processing',
|
|
511
1178
|
// shipping_status: tempOrder.shipping_status || 'unfulfilled',
|
|
512
1179
|
is_price_include_tax: tempOrder.is_price_include_tax ?? 1,
|
|
513
|
-
currency_format: tempOrder.currency_format ||
|
|
1180
|
+
currency_format: tempOrder.currency_format || 'symbol_first',
|
|
514
1181
|
is_deposit: tempOrder.is_deposit ?? 0,
|
|
515
|
-
deposit_amount: tempOrder.deposit_amount ||
|
|
516
|
-
shop_discount: tempOrder.shop_discount ||
|
|
517
|
-
surcharge_fee:
|
|
518
|
-
note: tempOrder.note ||
|
|
1182
|
+
deposit_amount: tempOrder.deposit_amount || '0.00',
|
|
1183
|
+
shop_discount: tempOrder.shop_discount || '0.00',
|
|
1184
|
+
surcharge_fee: tempOrder.surcharge_fee || '0.00',
|
|
1185
|
+
note: tempOrder.note || '',
|
|
1186
|
+
delivery_type: tempOrder.delivery_type || 'nil',
|
|
519
1187
|
schedule_date: scheduleDate,
|
|
520
|
-
|
|
1188
|
+
// created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
|
|
1189
|
+
bookings: (tempOrder.bookings || []).filter(booking => Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
|
|
521
1190
|
payments: tempOrder.payments || [],
|
|
522
|
-
// discount_list: tempOrder.discount_list || [],
|
|
523
1191
|
relation_forms: tempOrder.relation_forms || [],
|
|
524
|
-
form_record_ids: formRecordIds,
|
|
525
1192
|
// contacts: tempOrder.contacts || [],
|
|
526
|
-
contacts_info: tempOrder.contacts_info
|
|
1193
|
+
contacts_info: tempOrder.contacts_info && !Array.isArray(tempOrder.contacts_info) ? tempOrder.contacts_info : null,
|
|
527
1194
|
// holder: tempOrder.holder || null,
|
|
528
|
-
|
|
1195
|
+
summary: summary || tempOrder.summary || (0, _utils2.createEmptySummary)(),
|
|
529
1196
|
metadata: (() => {
|
|
530
1197
|
const {
|
|
531
1198
|
collect_pax: _collectPax,
|
|
532
1199
|
table_occupancy_duration: _tableOccupancyDuration,
|
|
533
1200
|
...rest
|
|
534
1201
|
} = tempOrder.metadata || {};
|
|
535
|
-
return {
|
|
1202
|
+
return {
|
|
1203
|
+
...rest
|
|
1204
|
+
};
|
|
536
1205
|
})(),
|
|
537
|
-
products: (tempOrder.products || []).map(
|
|
538
|
-
(product) => normalizeSubmitProduct(product)
|
|
539
|
-
)
|
|
1206
|
+
products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product))
|
|
540
1207
|
};
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return ((_a = p.metadata) == null ? void 0 : _a.is_rule) !== true;
|
|
1208
|
+
if (!enhance) return payload;
|
|
1209
|
+
const enhancedPayload = enhance(payload, {
|
|
1210
|
+
tempOrder,
|
|
1211
|
+
bookingUuid,
|
|
1212
|
+
now
|
|
547
1213
|
});
|
|
1214
|
+
return {
|
|
1215
|
+
...enhancedPayload,
|
|
1216
|
+
summary: enhancedPayload.summary ?? payload.summary
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
function mapPaymentItemToOrderPayment(paymentItem) {
|
|
1220
|
+
const item = paymentItem;
|
|
1221
|
+
const customPaymentId = item.custom_payment_id ?? item.id;
|
|
1222
|
+
const metadata = item.metadata && typeof item.metadata === 'object' ? {
|
|
1223
|
+
...item.metadata
|
|
1224
|
+
} : {};
|
|
1225
|
+
if (item.uuid && !metadata.unique_payment_number) {
|
|
1226
|
+
metadata.unique_payment_number = String(item.uuid);
|
|
1227
|
+
}
|
|
1228
|
+
const paymentMetadataKeys = ['rounding_rule', 'shop_wallet_pass_id', 'actual_paid_amount', 'change_given_amount'];
|
|
1229
|
+
for (const key of paymentMetadataKeys) {
|
|
1230
|
+
if (item[key] !== undefined && metadata[key] === undefined) {
|
|
1231
|
+
metadata[key] = item[key];
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
const timestamp = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
|
|
1235
|
+
const paymentTime = item.payment_time ?? timestamp;
|
|
1236
|
+
const createdAt = item.created_at ?? timestamp;
|
|
1237
|
+
return {
|
|
1238
|
+
...(item.order_payment_id !== undefined ? {
|
|
1239
|
+
order_payment_id: item.order_payment_id
|
|
1240
|
+
} : {}),
|
|
1241
|
+
amount: String(item.amount ?? '0.00'),
|
|
1242
|
+
code: String(item.code || ''),
|
|
1243
|
+
custom_payment_id: Number(customPaymentId ?? 0),
|
|
1244
|
+
...(item.custom_payment_type !== undefined ? {
|
|
1245
|
+
custom_payment_type: String(item.custom_payment_type)
|
|
1246
|
+
} : {}),
|
|
1247
|
+
name: String(item.name || ''),
|
|
1248
|
+
type: String(item.type || ''),
|
|
1249
|
+
...(item.voucher_id !== undefined ? {
|
|
1250
|
+
voucher_id: item.voucher_id
|
|
1251
|
+
} : {}),
|
|
1252
|
+
...(item.origin_amount !== undefined ? {
|
|
1253
|
+
origin_amount: String(item.origin_amount)
|
|
1254
|
+
} : {}),
|
|
1255
|
+
...(item.service_fee !== undefined ? {
|
|
1256
|
+
service_fee: String(item.service_fee)
|
|
1257
|
+
} : {}),
|
|
1258
|
+
...(item.status !== undefined ? {
|
|
1259
|
+
status: item.status
|
|
1260
|
+
} : {}),
|
|
1261
|
+
payment_time: paymentTime,
|
|
1262
|
+
created_at: createdAt,
|
|
1263
|
+
...(item.wallet_pass_usage_unit !== undefined ? {
|
|
1264
|
+
wallet_pass_usage_unit: item.wallet_pass_usage_unit
|
|
1265
|
+
} : {}),
|
|
1266
|
+
...(item.wallet_pass_use_value !== undefined ? {
|
|
1267
|
+
wallet_pass_use_value: item.wallet_pass_use_value
|
|
1268
|
+
} : {}),
|
|
1269
|
+
...(item.fund_record && typeof item.fund_record === 'object' && !Array.isArray(item.fund_record) ? {
|
|
1270
|
+
fund_record: {
|
|
1271
|
+
...item.fund_record
|
|
1272
|
+
}
|
|
1273
|
+
} : {}),
|
|
1274
|
+
metadata,
|
|
1275
|
+
...(item.rounding_amount !== undefined ? {
|
|
1276
|
+
rounding_amount: String(item.rounding_amount)
|
|
1277
|
+
} : {}),
|
|
1278
|
+
...(item.service_charge !== undefined ? {
|
|
1279
|
+
service_charge: item.service_charge
|
|
1280
|
+
} : {}),
|
|
1281
|
+
...(item.order_payment_type !== undefined ? {
|
|
1282
|
+
order_payment_type: item.order_payment_type
|
|
1283
|
+
} : {}),
|
|
1284
|
+
...(item.updated_at !== undefined ? {
|
|
1285
|
+
updated_at: item.updated_at
|
|
1286
|
+
} : {})
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
function mapPaymentItemsToOrderPayments(paymentItems, options = {}) {
|
|
1290
|
+
if (!Array.isArray(paymentItems)) return [];
|
|
1291
|
+
return paymentItems.filter(item => options.includeVoided || item.status !== 'voided').map(item => mapPaymentItemToOrderPayment(item));
|
|
548
1292
|
}
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* 历史 V1 加餐结构映射器。
|
|
1296
|
+
*
|
|
1297
|
+
* @deprecated 标准 Sales checkout 已统一提交结构。
|
|
1298
|
+
* 本函数仅保留以兼容历史接入方,未来会移除。新代码请勿再调用。
|
|
1299
|
+
*/
|
|
549
1300
|
function formatV1Product(products) {
|
|
550
|
-
return products.map(
|
|
1301
|
+
return products.map(product => {
|
|
551
1302
|
return {
|
|
552
1303
|
bundle: product.product_bundle,
|
|
553
1304
|
key: product.product_id,
|
|
554
|
-
option: product.
|
|
1305
|
+
option: product.product_sku?.option || [],
|
|
555
1306
|
product_id: product.product_id,
|
|
556
1307
|
product_variant_id: product.product_variant_id,
|
|
557
|
-
num: product.
|
|
558
|
-
note: String(product.note ??
|
|
1308
|
+
num: product.product_quantity,
|
|
1309
|
+
note: String(product.note ?? ''),
|
|
559
1310
|
rowKey: product.product_id,
|
|
560
1311
|
session: null,
|
|
561
|
-
unique: createUuidV4()
|
|
1312
|
+
unique: (0, _orderCollectionIdentity.createUuidV4)()
|
|
562
1313
|
};
|
|
563
1314
|
});
|
|
564
1315
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
1316
|
+
|
|
1317
|
+
/**
|
|
1318
|
+
* 判断 holder_id 是否已分配(非空)。
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* hasAssignedHolderId(12); // true
|
|
1322
|
+
* hasAssignedHolderId([]); // false
|
|
1323
|
+
*/
|
|
1324
|
+
function hasAssignedHolderId(value) {
|
|
1325
|
+
if (value === undefined || value === null || value === '') return false;
|
|
1326
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
1327
|
+
return true;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* 清空 tempOrder 购物车行上的 holder 分配(products / bookings / runtime origin)。
|
|
1332
|
+
* 移除或更换下单客户时调用,与 booking 页换客户清 holder 行为对齐。
|
|
1333
|
+
*
|
|
1334
|
+
* @example
|
|
1335
|
+
* clearTempOrderHolderAssignments(tempOrder);
|
|
1336
|
+
*/
|
|
1337
|
+
function clearTempOrderHolderAssignments(tempOrder) {
|
|
1338
|
+
let changed = false;
|
|
1339
|
+
const resetHolderField = (target, key = 'holder_id') => {
|
|
1340
|
+
if (!hasAssignedHolderId(target[key])) return;
|
|
1341
|
+
target[key] = null;
|
|
1342
|
+
changed = true;
|
|
1343
|
+
};
|
|
1344
|
+
for (const product of tempOrder.products || []) {
|
|
1345
|
+
if (product.metadata && typeof product.metadata === 'object') {
|
|
1346
|
+
resetHolderField(product.metadata);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
for (const booking of tempOrder.bookings || []) {
|
|
1350
|
+
const bookingRecord = booking;
|
|
1351
|
+
if (booking.metadata && typeof booking.metadata === 'object') {
|
|
1352
|
+
resetHolderField(booking.metadata);
|
|
1353
|
+
}
|
|
1354
|
+
if (bookingRecord.holder !== undefined && bookingRecord.holder !== null) {
|
|
1355
|
+
delete bookingRecord.holder;
|
|
1356
|
+
changed = true;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
const productsByUid = tempOrder._extend?.productsByUid;
|
|
1360
|
+
if (productsByUid && typeof productsByUid === 'object') {
|
|
1361
|
+
for (const entry of Object.values(productsByUid)) {
|
|
1362
|
+
const origin = entry?.origin;
|
|
1363
|
+
if (!origin || typeof origin !== 'object') continue;
|
|
1364
|
+
if (origin.metadata && typeof origin.metadata === 'object') {
|
|
1365
|
+
resetHolderField(origin.metadata);
|
|
1366
|
+
}
|
|
1367
|
+
if (origin._extend && typeof origin._extend === 'object') {
|
|
1368
|
+
resetHolderField(origin._extend);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return changed;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* 读取购物车行的 stable uid(优先 metadata.unique_identification_number)。
|
|
1377
|
+
*
|
|
1378
|
+
* @example
|
|
1379
|
+
* getOrderProductLineUid({ metadata: { unique_identification_number: 'line-1' } }); // 'line-1'
|
|
1380
|
+
*/
|
|
1381
|
+
function getOrderProductLineUid(product) {
|
|
1382
|
+
if (!product || typeof product !== 'object') return null;
|
|
1383
|
+
const uid = product.metadata?.unique_identification_number ?? product.unique_identification_number;
|
|
1384
|
+
if (uid === undefined || uid === null || uid === '') return null;
|
|
1385
|
+
return String(uid);
|
|
1386
|
+
}
|
|
1387
|
+
function getRuntimeProductOrigin(tempOrder, product) {
|
|
1388
|
+
const uid = getOrderProductLineUid(product);
|
|
1389
|
+
if (uid && tempOrder?._extend?.productsByUid?.[uid]?.origin) {
|
|
1390
|
+
return tempOrder._extend.productsByUid[uid].origin;
|
|
1391
|
+
}
|
|
1392
|
+
const matchedProduct = (tempOrder?.products || []).find(item => item === product || getOrderProductLineUid(item) === uid || String(item?.product_id ?? item?.id ?? '') === String(product?.product_id ?? product?.id ?? ''));
|
|
1393
|
+
const matchedUid = matchedProduct ? getOrderProductLineUid(matchedProduct) : '';
|
|
1394
|
+
return matchedUid ? tempOrder?._extend?.productsByUid?.[matchedUid]?.origin || null : null;
|
|
1395
|
+
}
|
|
1396
|
+
function isHolderConfigRequired(holderConfig) {
|
|
1397
|
+
if (!holderConfig || typeof holderConfig !== 'object') return false;
|
|
1398
|
+
if (holderConfig.status === 'disable') return false;
|
|
1399
|
+
return Number(holderConfig.required) === 1;
|
|
1400
|
+
}
|
|
1401
|
+
function productRequiresFormSubject(tempOrder, product) {
|
|
1402
|
+
const _orderProduct = tempOrder?.products?.find(item => {
|
|
1403
|
+
return item.metadata.unique_identification_number === product._id || item.product_id === product.id;
|
|
1404
|
+
});
|
|
1405
|
+
const runtimeOrigin = getRuntimeProductOrigin(tempOrder, product);
|
|
1406
|
+
return isHolderConfigRequired(_orderProduct?.metadata?.holder_config) || isHolderConfigRequired(runtimeOrigin?.holder_config) || isHolderConfigRequired(product?.holder_config);
|
|
1407
|
+
}
|
|
1408
|
+
function resolveIsFormSubject(tempOrder, product) {
|
|
1409
|
+
debugger;
|
|
1410
|
+
// 旧版预约维度的 holder 类型仍然生效;新版则从当前商品 holder_config 判断。
|
|
1411
|
+
if (tempOrder?.holder?.type === 'form') return true;
|
|
1412
|
+
if (product) return productRequiresFormSubject(tempOrder, product);
|
|
1413
|
+
return (tempOrder?.products || []).some(item => productRequiresFormSubject(tempOrder, item));
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* 判断展示字段是否为空(含 i18n 对象全空)。
|
|
1418
|
+
*
|
|
1419
|
+
* @example
|
|
1420
|
+
* isEmptyOrderProductDisplayValue(''); // true
|
|
1421
|
+
* isEmptyOrderProductDisplayValue({ auto: '桌台费' }); // false
|
|
1422
|
+
*/
|
|
1423
|
+
function isEmptyOrderProductDisplayValue(value) {
|
|
1424
|
+
if (value === undefined || value === null) return true;
|
|
1425
|
+
if (typeof value === 'string') return value.trim() === '';
|
|
1426
|
+
if (typeof value === 'object') {
|
|
1427
|
+
const record = value;
|
|
1428
|
+
return !Object.values(record).some(item => typeof item === 'string' && item.trim() !== '');
|
|
1429
|
+
}
|
|
1430
|
+
return false;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
/**
|
|
1434
|
+
* calcDiscount / applyDiscount 回写时 Rules 往往不带 product_title 等展示字段;
|
|
1435
|
+
* 用旧行补齐,避免编辑态 hydrate 后标题被冲掉。
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* mergeOrderProductDisplayFields(
|
|
1439
|
+
* { product_title: { auto: '桌台费' }, metadata: { unique_identification_number: 'u1' } },
|
|
1440
|
+
* { selling_price: '10.00', metadata: { unique_identification_number: 'u1' } },
|
|
1441
|
+
* );
|
|
1442
|
+
*/
|
|
1443
|
+
function mergeOrderProductDisplayFields(previous, next) {
|
|
1444
|
+
const merged = {
|
|
1445
|
+
...next
|
|
1446
|
+
};
|
|
1447
|
+
const displayFields = ['product_title', 'product_name', 'product_cover', 'cover', 'product_cover', 'variant_title', 'product_sku', 'payment_price'];
|
|
1448
|
+
displayFields.forEach(field => {
|
|
1449
|
+
if (isEmptyOrderProductDisplayValue(merged[field]) && !isEmptyOrderProductDisplayValue(previous[field])) {
|
|
1450
|
+
merged[field] = previous[field];
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
if (previous.metadata || next.metadata) {
|
|
1454
|
+
merged.metadata = {
|
|
1455
|
+
...(previous.metadata || {}),
|
|
1456
|
+
...(next.metadata || {})
|
|
1457
|
+
};
|
|
1458
|
+
['product_title', 'product_name'].forEach(field => {
|
|
1459
|
+
if (isEmptyOrderProductDisplayValue(merged.metadata[field]) && !isEmptyOrderProductDisplayValue(previous.metadata?.[field])) {
|
|
1460
|
+
merged.metadata[field] = previous.metadata[field];
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
if (previous._extend && !merged._extend) {
|
|
1465
|
+
merged._extend = previous._extend;
|
|
1466
|
+
}
|
|
1467
|
+
return merged;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
/**
|
|
1471
|
+
* 按 uid 索引 tempOrder.products,供 applyDiscount 合并展示字段。
|
|
1472
|
+
*
|
|
1473
|
+
* @example
|
|
1474
|
+
* indexOrderProductsByUid([{ metadata: { unique_identification_number: 'u1' } }]);
|
|
1475
|
+
*/
|
|
1476
|
+
function indexOrderProductsByUid(products) {
|
|
1477
|
+
const map = new Map();
|
|
1478
|
+
(products || []).forEach((product, index) => {
|
|
1479
|
+
const uid = getOrderProductLineUid(product);
|
|
1480
|
+
if (uid) {
|
|
1481
|
+
map.set(uid, product);
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
map.set(`__index__:${index}`, product);
|
|
1485
|
+
});
|
|
1486
|
+
return map;
|
|
1487
|
+
}
|