@pisell/pisellos 0.0.568 → 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/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/dist/model/strategy/adapter/walletPass/utils.js +7 -4
- 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/utils/cartProduct.js +26 -5
- 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/Discount/index.d.ts +2 -1
- package/dist/modules/Discount/index.js +37 -9
- package/dist/modules/Discount/types.d.ts +1 -0
- package/dist/modules/OpenData/index.d.ts +8 -0
- package/dist/modules/OpenData/index.js +36 -16
- package/dist/modules/Order/index.d.ts +448 -23
- package/dist/modules/Order/index.js +5417 -561
- 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 +465 -703
- 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 +44 -29
- 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 +221 -109
- 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/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/server/index.d.ts +462 -8
- package/dist/server/index.js +6112 -656
- 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/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 +1393 -516
- 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 +278 -66
- package/dist/server/modules/resource/index.d.ts +2 -3
- package/dist/server/modules/resource/index.js +108 -86
- package/dist/server/modules/schedule/index.d.ts +6 -4
- package/dist/server/modules/schedule/index.js +116 -85
- package/dist/server/test.json +713 -0
- package/dist/server/types.d.ts +2 -0
- package/dist/server/utils/product.js +2 -2
- 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.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +394 -25
- package/dist/solution/BookingTicket/index.js +2506 -443
- 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 +11 -3
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +20 -8
- 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/Checkout/index.d.ts +1 -0
- package/dist/solution/Checkout/index.js +25 -34
- package/dist/solution/Checkout/utils/index.js +4 -4
- package/dist/solution/RegisterAndLogin/config.js +2 -10
- 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 +499 -434
- 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 +4 -4
- 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 +29 -20
- package/dist/solution/VenueBooking/index.js +301 -213
- 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/lib/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/lib/model/strategy/adapter/walletPass/utils.js +6 -4
- package/lib/modules/BaseModule.d.ts +2 -2
- package/lib/modules/BaseModule.js +4 -4
- 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/utils/cartProduct.js +27 -5
- package/lib/modules/Cart/utils/changePrice.js +20 -14
- package/lib/modules/Customer/index.d.ts +20 -0
- package/lib/modules/Customer/index.js +63 -10
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Discount/index.d.ts +2 -1
- package/lib/modules/Discount/index.js +18 -2
- package/lib/modules/Discount/types.d.ts +1 -0
- package/lib/modules/OpenData/index.d.ts +8 -0
- package/lib/modules/OpenData/index.js +21 -3
- package/lib/modules/Order/index.d.ts +448 -23
- package/lib/modules/Order/index.js +3641 -308
- package/lib/modules/Order/types.d.ts +693 -88
- package/lib/modules/Order/types.js +55 -1
- 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 +974 -138
- package/lib/modules/Payment/index.d.ts +10 -9
- package/lib/modules/Payment/index.js +30 -124
- package/lib/modules/Payment/types.d.ts +40 -16
- package/lib/modules/Payment/utils.d.ts +1 -1
- package/lib/modules/Payment/utils.js +4 -3
- package/lib/modules/Payment/walletpass.js +16 -6
- package/lib/modules/Product/types.d.ts +29 -7
- package/lib/modules/ProductList/index.d.ts +17 -13
- package/lib/modules/ProductList/index.js +92 -51
- package/lib/modules/ProductList/types.d.ts +17 -0
- package/lib/modules/Quotation/index.d.ts +22 -2
- package/lib/modules/Quotation/index.js +76 -20
- package/lib/modules/Quotation/types.d.ts +19 -0
- 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 +152 -60
- package/lib/modules/Rules/types.d.ts +14 -3
- package/lib/modules/SalesSummary/index.d.ts +23 -26
- package/lib/modules/SalesSummary/index.js +84 -16
- package/lib/modules/SalesSummary/types.d.ts +9 -1
- package/lib/modules/SalesSummary/utils.d.ts +3 -22
- package/lib/modules/SalesSummary/utils.js +616 -111
- package/lib/modules/Schedule/getDateIsInSchedule.js +14 -7
- package/lib/modules/Schedule/index.d.ts +18 -5
- package/lib/modules/Schedule/index.js +49 -14
- package/lib/modules/Schedule/types.d.ts +2 -0
- package/lib/modules/Summary/index.js +2 -2
- 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 +33 -0
- package/lib/plugins/app.d.ts +2 -0
- package/lib/plugins/request.d.ts +1 -0
- package/lib/server/index.d.ts +462 -8
- package/lib/server/index.js +3901 -205
- 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 +21 -0
- package/lib/server/modules/order/index.d.ts +207 -14
- package/lib/server/modules/order/index.js +1324 -141
- package/lib/server/modules/order/types.d.ts +76 -5
- package/lib/server/modules/order/types.js +11 -1
- package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
- package/lib/server/modules/order/utils/filterBookings.js +119 -11
- package/lib/server/modules/order/utils/filterOrders.js +238 -13
- 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 +588 -97
- package/lib/server/modules/products/types.d.ts +34 -1
- package/lib/server/modules/products/types.js +3 -0
- package/lib/server/modules/quotation/index.d.ts +39 -0
- package/lib/server/modules/quotation/index.js +145 -1
- package/lib/server/modules/resource/index.d.ts +2 -3
- package/lib/server/modules/resource/index.js +71 -45
- package/lib/server/modules/schedule/index.d.ts +6 -4
- package/lib/server/modules/schedule/index.js +55 -44
- package/lib/server/test.json +713 -0
- package/lib/server/types.d.ts +2 -0
- package/lib/server/utils/product.js +2 -2
- package/lib/server/utils/small-ticket.d.ts +71 -0
- package/lib/server/utils/small-ticket.js +926 -0
- 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.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +394 -25
- package/lib/solution/BookingTicket/index.js +1350 -76
- package/lib/solution/BookingTicket/types.d.ts +191 -6
- package/lib/solution/BookingTicket/types.js +71 -10
- 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 +24 -3
- 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 +4 -2
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +14 -2
- 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/Checkout/index.d.ts +1 -0
- package/lib/solution/Checkout/index.js +18 -19
- package/lib/solution/Checkout/utils/index.js +4 -4
- package/lib/solution/RegisterAndLogin/config.js +2 -10
- package/lib/solution/Sales/index.d.ts +50 -5
- package/lib/solution/Sales/index.js +296 -39
- package/lib/solution/Sales/types.d.ts +26 -2
- package/lib/solution/ScanOrder/index.d.ts +27 -21
- package/lib/solution/ScanOrder/index.js +144 -103
- package/lib/solution/ScanOrder/types.d.ts +33 -11
- package/lib/solution/ScanOrder/types.js +4 -5
- package/lib/solution/ScanOrder/utils.d.ts +4 -1
- package/lib/solution/ScanOrder/utils.js +98 -26
- package/lib/solution/ShopDiscount/index.js +3 -3
- 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 +29 -20
- package/lib/solution/VenueBooking/index.js +169 -94
- package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +9 -3
- package/lib/solution/index.d.ts +2 -0
- package/lib/solution/index.js +22 -0
- package/lib/types/index.d.ts +11 -1
- package/package.json +1 -1
- package/dist/solution/Checkout/appointmentDemo.json +0 -1
- package/lib/solution/Checkout/appointmentDemo.json +0 -1
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "buildManualProductDiscountItem", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _manualProductDiscount.buildManualProductDiscountItem;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
6
12
|
exports.buildSubmitPayload = buildSubmitPayload;
|
|
13
|
+
exports.calculateOrderProductsDeposit = calculateOrderProductsDeposit;
|
|
14
|
+
exports.clearTempOrderHolderAssignments = clearTempOrderHolderAssignments;
|
|
7
15
|
exports.composeLinePrice = composeLinePrice;
|
|
8
16
|
exports.createDefaultOrderRulesHooks = createDefaultOrderRulesHooks;
|
|
9
17
|
exports.createDefaultTempOrder = createDefaultTempOrder;
|
|
@@ -13,22 +21,111 @@ Object.defineProperty(exports, "createEmptySummary", {
|
|
|
13
21
|
return _utils2.createEmptySummary;
|
|
14
22
|
}
|
|
15
23
|
});
|
|
16
|
-
exports
|
|
24
|
+
Object.defineProperty(exports, "createUuidV4", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _orderCollectionIdentity.createUuidV4;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
17
30
|
exports.ensureCartItemOriginHolder = ensureCartItemOriginHolder;
|
|
18
|
-
exports
|
|
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
|
+
});
|
|
19
44
|
exports.formatDateTime = formatDateTime;
|
|
20
45
|
exports.formatV1Product = formatV1Product;
|
|
21
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;
|
|
22
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;
|
|
23
67
|
exports.mergeRelationForms = void 0;
|
|
68
|
+
exports.normalizeBookingIsAll = normalizeBookingIsAll;
|
|
69
|
+
exports.normalizeBookingSubType = normalizeBookingSubType;
|
|
70
|
+
exports.normalizeOrderProductDiscountList = normalizeOrderProductDiscountList;
|
|
71
|
+
exports.normalizeProductSkuOptions = normalizeProductSkuOptions;
|
|
24
72
|
exports.normalizeSubmitBooking = normalizeSubmitBooking;
|
|
25
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
|
+
});
|
|
26
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
|
+
});
|
|
27
116
|
exports.sumOptionUnitPrice = sumOptionUnitPrice;
|
|
117
|
+
Object.defineProperty(exports, "syncManualProductDiscountProductNum", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function () {
|
|
120
|
+
return _manualProductDiscount.syncManualProductDiscountProductNum;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
28
123
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
29
124
|
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
30
125
|
var _utils = require("../Holder/utils");
|
|
31
126
|
var _utils2 = require("../../solution/ScanOrder/utils");
|
|
127
|
+
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
128
|
+
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
32
129
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
130
|
/**
|
|
34
131
|
* 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
|
|
@@ -52,30 +149,274 @@ function composeLinePrice(params) {
|
|
|
52
149
|
let total = new _decimal.default(Number(mainPrice) || 0);
|
|
53
150
|
if (Array.isArray(bundle)) {
|
|
54
151
|
for (const item of bundle) {
|
|
55
|
-
|
|
56
|
-
const
|
|
152
|
+
// markdown(减价)按带符号净额取减;markup/原价维持相加。
|
|
153
|
+
const signedUnit = getBundleSignedUnit(item, {
|
|
154
|
+
useOriginal: useOriginalBundle
|
|
155
|
+
});
|
|
57
156
|
const rawNum = item?.num ?? item?.quantity ?? 1;
|
|
58
157
|
const num = new _decimal.default(Number(rawNum) || 0);
|
|
59
|
-
total = total.plus(
|
|
158
|
+
total = total.plus(signedUnit.times(num));
|
|
60
159
|
}
|
|
61
160
|
}
|
|
62
161
|
return total.toDecimalPlaces(2).toFixed(2);
|
|
63
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
|
+
}
|
|
64
185
|
|
|
65
186
|
/**
|
|
66
|
-
* 计算 option 单价合计:Σ(option.
|
|
187
|
+
* 计算 option 单价合计:Σ(option.add_price × option.num)。
|
|
188
|
+
* 兼容入参仍带旧 `price` 的调用方,但运行时归一化后只维护 `add_price`。
|
|
67
189
|
* 在新语义 v2 下,main_product_original_price = source_product_price + 本函数结果。
|
|
68
190
|
*/
|
|
69
191
|
function sumOptionUnitPrice(options) {
|
|
70
192
|
let total = new _decimal.default(0);
|
|
71
193
|
if (!Array.isArray(options)) return total;
|
|
72
194
|
for (const opt of options) {
|
|
73
|
-
const price = new _decimal.default(Number(opt?.price) || 0);
|
|
195
|
+
const price = new _decimal.default(Number(opt?.add_price ?? opt?.price) || 0);
|
|
74
196
|
const num = new _decimal.default(Number(opt?.num) || 0);
|
|
75
197
|
total = total.plus(price.times(num));
|
|
76
198
|
}
|
|
77
199
|
return total;
|
|
78
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
|
+
}
|
|
79
420
|
|
|
80
421
|
/**
|
|
81
422
|
* OrderModule 默认 Rules 钩子工厂。
|
|
@@ -89,7 +430,7 @@ function sumOptionUnitPrice(options) {
|
|
|
89
430
|
* 不含折扣。**权威源**。
|
|
90
431
|
* - `metadata.main_product_original_price` = source + Σ(option.price × option.num)(含 option、不含折扣)。
|
|
91
432
|
* - `metadata.main_product_selling_price` = main_original − 主商品券 per-unit amount(含 option、含折扣)。
|
|
92
|
-
* - `payment_price`:出站 payload
|
|
433
|
+
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
93
434
|
*
|
|
94
435
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
95
436
|
* - `getProduct.price` / `getProduct.original_price` 回传 **source-level 主价**
|
|
@@ -106,16 +447,206 @@ function sumOptionUnitPrice(options) {
|
|
|
106
447
|
*
|
|
107
448
|
* 导出为纯函数方便单测直接驱动钩子,不依赖 OrderModule 实例。
|
|
108
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
|
+
}
|
|
109
602
|
function createDefaultOrderRulesHooks() {
|
|
110
603
|
const toUnitPriceString = (totalLike, num) => {
|
|
111
604
|
const effectiveNum = Number(num) > 0 ? Number(num) : 1;
|
|
112
605
|
return new _decimal.default(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
|
|
113
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
|
+
});
|
|
644
|
+
};
|
|
114
645
|
return {
|
|
115
646
|
getProduct: product => {
|
|
116
647
|
// source_product_price 是权威源;兜底链:source → mainSelling − options(反推)→ 行 selling_price
|
|
117
648
|
const metadataAny = product.metadata || {};
|
|
118
|
-
const optionSum = sumOptionUnitPrice(product
|
|
649
|
+
const optionSum = sumOptionUnitPrice(getProductSkuOptions(product));
|
|
119
650
|
let sourcePrice;
|
|
120
651
|
if (metadataAny.source_product_price !== undefined) {
|
|
121
652
|
sourcePrice = String(metadataAny.source_product_price);
|
|
@@ -136,9 +667,9 @@ function createDefaultOrderRulesHooks() {
|
|
|
136
667
|
id: product.product_id,
|
|
137
668
|
// Rules 引擎用 _id 作为 processedProductsMap 键;必须与购物车行级 identity 一致,
|
|
138
669
|
// 否则同 SKU 不同小料会在 calcDiscount 重组时互相覆盖。
|
|
139
|
-
// 不透明 identity 契约下,normalizeOrderProduct /
|
|
670
|
+
// 不透明 identity 契约下,normalizeOrderProduct / hydrate 已保证唯一值存在;
|
|
140
671
|
// 留 fingerprint 分支仅作 Rules 单测里直接传裸 product 时的兜底。
|
|
141
|
-
_id: product.
|
|
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)}`,
|
|
142
673
|
// Rules 内部 getProductTotalPrice / getProductOriginTotalPrice 会各自再叠加 bundle + option,
|
|
143
674
|
// 所以这里必须喂 source-level(不含 option、不含 bundle、不含折扣)单价,避免双加 option。
|
|
144
675
|
price: sourcePrice,
|
|
@@ -150,18 +681,23 @@ function createDefaultOrderRulesHooks() {
|
|
|
150
681
|
num: product.num || 1,
|
|
151
682
|
discount_list: product.discount_list || [],
|
|
152
683
|
bundle: product.product_bundle || [],
|
|
153
|
-
booking_id: product.
|
|
684
|
+
booking_id: product.metadata?.booking_id || null,
|
|
154
685
|
isClient: false,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
|
158
694
|
};
|
|
159
695
|
},
|
|
160
696
|
setProduct: (product, values) => {
|
|
161
697
|
const nextNum = Number(values.quantity ?? product.num ?? 1) || 1;
|
|
162
698
|
const metadataAny = product.metadata || {};
|
|
163
699
|
const existedSource = metadataAny.source_product_price ?? product.selling_price ?? '0';
|
|
164
|
-
const nextOptions = product
|
|
700
|
+
const nextOptions = getProductSkuOptions(product);
|
|
165
701
|
const optionSum = sumOptionUnitPrice(nextOptions);
|
|
166
702
|
|
|
167
703
|
// Rules 返回的 main_product_selling_price / price / total 均为 source-level。
|
|
@@ -176,7 +712,7 @@ function createDefaultOrderRulesHooks() {
|
|
|
176
712
|
// 含 option 的 main_product_*
|
|
177
713
|
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
178
714
|
const nextMainOriginalPrice = new _decimal.default(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
179
|
-
const nextBundle = values.bundle
|
|
715
|
+
const nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
|
|
180
716
|
const composedSellingPrice = composeLinePrice({
|
|
181
717
|
mainPrice: nextMainSellingPrice,
|
|
182
718
|
bundle: nextBundle
|
|
@@ -186,10 +722,15 @@ function createDefaultOrderRulesHooks() {
|
|
|
186
722
|
bundle: nextBundle,
|
|
187
723
|
useOriginalBundle: true
|
|
188
724
|
});
|
|
725
|
+
const finalOriginalPrice = resolveManualOverrideLineOriginalPrice({
|
|
726
|
+
num: nextNum,
|
|
727
|
+
metadata: metadataAny,
|
|
728
|
+
lineOriginalPrice: product.original_price
|
|
729
|
+
}, composedOriginalPrice);
|
|
189
730
|
return {
|
|
190
731
|
...product,
|
|
191
732
|
selling_price: composedSellingPrice,
|
|
192
|
-
original_price:
|
|
733
|
+
original_price: finalOriginalPrice,
|
|
193
734
|
discount_list: values.discount_list ?? product.discount_list,
|
|
194
735
|
num: values.quantity ?? product.num,
|
|
195
736
|
product_bundle: nextBundle,
|
|
@@ -291,14 +832,6 @@ const getAllDiscountList = cartItem => {
|
|
|
291
832
|
|
|
292
833
|
// ─── 以下为从 ScanOrder/utils.ts 迁入的 Order 专属工具函数 ───
|
|
293
834
|
exports.getAllDiscountList = getAllDiscountList;
|
|
294
|
-
function createUuidV4() {
|
|
295
|
-
const template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
|
|
296
|
-
return template.replace(/[xy]/g, char => {
|
|
297
|
-
const randomValue = Math.floor(Math.random() * 16);
|
|
298
|
-
const value = char === 'x' ? randomValue : randomValue & 0x3 | 0x8;
|
|
299
|
-
return value.toString(16);
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
835
|
function isTempOrder(data) {
|
|
303
836
|
if (!data || typeof data !== 'object') return false;
|
|
304
837
|
if (!Array.isArray(data.products)) return false;
|
|
@@ -315,70 +848,86 @@ function formatDateTime(date) {
|
|
|
315
848
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
316
849
|
}
|
|
317
850
|
function normalizeSubmitPlatform(platform) {
|
|
318
|
-
|
|
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;
|
|
319
857
|
}
|
|
320
858
|
|
|
321
|
-
//
|
|
322
|
-
// tempOrder / UI 运行时一律使用 product_option_item_id。仅保留后端契约字段,
|
|
323
|
-
// 与 src/modules/Cart/utils/cartProduct.ts#formatOptionsToOrigin 形状一致。
|
|
859
|
+
// 后端 checkout 协议字段 option_group_item_id;tempOrder 内部也保持同一字段名。
|
|
324
860
|
function formatSubmitOptionItems(options) {
|
|
325
861
|
if (!Array.isArray(options)) return [];
|
|
326
|
-
return options.map(d =>
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
+
});
|
|
331
874
|
}
|
|
332
875
|
function toBundleNumber(value, fallback = 0) {
|
|
333
876
|
const parsed = Number(value);
|
|
334
877
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
335
878
|
}
|
|
336
|
-
function
|
|
879
|
+
function toMoneyString(value) {
|
|
337
880
|
const parsed = Number(value);
|
|
338
881
|
if (Number.isFinite(parsed)) return parsed.toFixed(2);
|
|
339
882
|
if (value === null || value === undefined || value === '') return '0.00';
|
|
340
883
|
return String(value);
|
|
341
884
|
}
|
|
342
885
|
|
|
343
|
-
//
|
|
344
|
-
// 同时把 Summary / Rules 运行时写到 bundle 顶层的 surcharge_fee / relation_surcharge_ids
|
|
345
|
-
// 和来自 _origin 的 product_discount_difference 汇总到 metadata。
|
|
346
|
-
// 保留原对象上已有字段(如 discount_list、metadata.custom_product_bundle_map_id)
|
|
347
|
-
// 以兼容运行时 bundle 归一化、Rules、Summary 的消费。
|
|
886
|
+
// 出站补齐:只输出后端 checkout 协议字段,运行时/详情展示字段不进入 bundle payload。
|
|
348
887
|
function formatSubmitBundleItems(bundle) {
|
|
349
888
|
if (!Array.isArray(bundle)) return [];
|
|
350
889
|
return bundle.map(b => {
|
|
351
890
|
const rawBundle = b && typeof b === 'object' ? b : {};
|
|
352
891
|
const existedMetadata = rawBundle.metadata && typeof rawBundle.metadata === 'object' ? rawBundle.metadata : {};
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
// rawBundle.custom_price ?? rawBundle.bundle_selling_price ?? rawBundle.price,
|
|
358
|
-
// );
|
|
892
|
+
const {
|
|
893
|
+
custom_product_bundle_map_id: _customProductBundleMapId,
|
|
894
|
+
...submitMetadata
|
|
895
|
+
} = existedMetadata;
|
|
359
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;
|
|
360
903
|
const relationSurchargeIds = Array.isArray(rawBundle.relation_surcharge_ids) ? rawBundle.relation_surcharge_ids : Array.isArray(existedMetadata.relation_surcharge_ids) ? existedMetadata.relation_surcharge_ids : [];
|
|
361
|
-
const surchargeFee =
|
|
904
|
+
const surchargeFee = toMoneyString(rawBundle.surcharge_fee ?? existedMetadata.surcharge_fee);
|
|
362
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;
|
|
363
909
|
return {
|
|
364
|
-
...rawBundle,
|
|
365
910
|
is_charge_tax: rawBundle.is_charge_tax ?? 0,
|
|
366
|
-
tax_fee: toBundleNumber(rawBundle.tax_fee, 0),
|
|
367
911
|
bundle_variant_id: rawBundle.bundle_variant_id ?? 0,
|
|
368
|
-
num
|
|
912
|
+
num,
|
|
913
|
+
quantity: toBundleNumber(rawBundle.quantity ?? rawBundle.num, num),
|
|
369
914
|
extension_id: rawBundle.extension_id ?? 0,
|
|
370
915
|
extension_type: rawBundle.extension_type ?? 'normal',
|
|
371
|
-
price:
|
|
372
|
-
price_type:
|
|
373
|
-
price_type_ext: rawBundle.price_type_ext ?? '',
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
bundle_selling_price: sellingPriceNum,
|
|
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,
|
|
377
921
|
option: formatSubmitOptionItems(rawBundle.option),
|
|
378
|
-
bundle_group_id: rawBundle?.group_id,
|
|
379
|
-
bundle_id: rawBundle?.id,
|
|
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,
|
|
380
926
|
metadata: {
|
|
381
|
-
...
|
|
927
|
+
...submitMetadata,
|
|
928
|
+
...(hasSubmitBundleDiscounts && bundleMapId !== undefined ? {
|
|
929
|
+
custom_product_bundle_map_id: bundleMapId
|
|
930
|
+
} : {}),
|
|
382
931
|
surcharge_fee: surchargeFee,
|
|
383
932
|
relation_surcharge_ids: relationSurchargeIds,
|
|
384
933
|
product_discount_difference: productDiscountDifference
|
|
@@ -395,7 +944,7 @@ function formatSubmitBundleItems(bundle) {
|
|
|
395
944
|
* = `metadata.main_product_selling_price` + Σ(bundle_selling_price × num)。
|
|
396
945
|
* - `original_price`:**行 composite 券前单价**
|
|
397
946
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
398
|
-
* - `payment_price
|
|
947
|
+
* - `payment_price`:兼容后端的出站字段,行 composite 已减整单折扣均摊(无折扣时与 `selling_price` 同义)。
|
|
399
948
|
* - `metadata.source_product_price`:主商品/variant 基础价(不含 option、不含折扣),权威源。
|
|
400
949
|
* - `metadata.main_product_original_price`:含 option、不含折扣。
|
|
401
950
|
* - `metadata.main_product_selling_price`:含 option、含主商品折扣。
|
|
@@ -405,43 +954,72 @@ function formatSubmitBundleItems(bundle) {
|
|
|
405
954
|
*/
|
|
406
955
|
function normalizeSubmitProduct(product) {
|
|
407
956
|
const {
|
|
408
|
-
|
|
409
|
-
identity_key,
|
|
957
|
+
unique_identification_number: _runtimeUid,
|
|
410
958
|
...submitProduct
|
|
411
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`];
|
|
412
971
|
const rawMetadata = submitProduct.metadata || {};
|
|
413
972
|
const bookingUid = rawMetadata.booking_uid;
|
|
414
973
|
const cleanMetadata = {};
|
|
415
974
|
if (rawMetadata.unique_identification_number) {
|
|
416
975
|
cleanMetadata.unique_identification_number = rawMetadata.unique_identification_number;
|
|
417
976
|
}
|
|
418
|
-
const priceMetaKeys = ['main_product_original_price', 'main_product_selling_price', 'source_product_price', '
|
|
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'];
|
|
419
978
|
for (const key of priceMetaKeys) {
|
|
420
979
|
if (rawMetadata[key] !== undefined) {
|
|
421
980
|
cleanMetadata[key] = rawMetadata[key];
|
|
422
981
|
}
|
|
423
982
|
}
|
|
983
|
+
cleanMetadata.product_discount_difference = rawMetadata.product_discount_difference ?? '';
|
|
424
984
|
if (rawMetadata.price_breakdown) {
|
|
425
985
|
cleanMetadata.price_breakdown = rawMetadata.price_breakdown;
|
|
426
986
|
}
|
|
427
987
|
if (rawMetadata.is_rule !== undefined) {
|
|
428
988
|
cleanMetadata.is_rule = rawMetadata.is_rule;
|
|
429
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
|
+
};
|
|
430
997
|
return {
|
|
431
|
-
...
|
|
998
|
+
...productRest,
|
|
432
999
|
...(bookingUid ? {
|
|
433
1000
|
booking_uid: bookingUid
|
|
434
1001
|
} : {}),
|
|
435
|
-
|
|
436
|
-
|
|
1002
|
+
product_quantity: toBundleNumber(num ?? submitProduct.product_quantity, 1),
|
|
1003
|
+
product_sku: productSku,
|
|
1004
|
+
discount_list: collectSubmitProductDiscountList(submitProduct),
|
|
437
1005
|
product_bundle: formatSubmitBundleItems(submitProduct.product_bundle),
|
|
438
1006
|
metadata: cleanMetadata,
|
|
439
|
-
// 出站兼容:后端消费 payment_price
|
|
440
|
-
//
|
|
441
|
-
payment_price: submitProduct.selling_price
|
|
1007
|
+
// 出站兼容:后端消费 payment_price 字段(行 composite 已减整单折扣均摊)。
|
|
1008
|
+
// 由整单折扣均摊层产出;缺省(无折扣)时与 selling_price 同义。
|
|
1009
|
+
payment_price: submitProduct.payment_price ?? submitProduct.selling_price
|
|
442
1010
|
};
|
|
443
1011
|
}
|
|
444
|
-
const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax'];
|
|
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
|
+
}
|
|
445
1023
|
function normalizeSubmitBooking(booking) {
|
|
446
1024
|
const rawMetadata = booking.metadata || {};
|
|
447
1025
|
const cleanMetadata = {};
|
|
@@ -450,8 +1028,18 @@ function normalizeSubmitBooking(booking) {
|
|
|
450
1028
|
cleanMetadata[key] = rawMetadata[key];
|
|
451
1029
|
}
|
|
452
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;
|
|
453
1036
|
return {
|
|
454
1037
|
...booking,
|
|
1038
|
+
...(shouldRestoreSelectDate && selectDateFromStartDate ? {
|
|
1039
|
+
select_date: selectDateFromStartDate
|
|
1040
|
+
} : {}),
|
|
1041
|
+
is_all: normalizeBookingIsAll(bookingRecord),
|
|
1042
|
+
sub_type: normalizeBookingSubType(bookingRecord),
|
|
455
1043
|
metadata: cleanMetadata
|
|
456
1044
|
};
|
|
457
1045
|
}
|
|
@@ -479,27 +1067,26 @@ function resolveSubmitCollectPax(tempOrder) {
|
|
|
479
1067
|
return normalizeSubmitCollectPaxValue(tempOrder.metadata?.collect_pax);
|
|
480
1068
|
}
|
|
481
1069
|
function createDefaultTempOrder(params) {
|
|
482
|
-
const summary = params.summary || (0, _utils2.createEmptySummary)();
|
|
483
1070
|
return {
|
|
484
1071
|
order_id: null,
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
business_code: 'appointment_booking',
|
|
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,
|
|
492
1078
|
platform: 'h5',
|
|
493
1079
|
sales_channel: 'my_pisel',
|
|
494
1080
|
order_sales_channel: 'online_store',
|
|
495
1081
|
status: 'normal',
|
|
496
1082
|
payment_status: 'payment_processing',
|
|
497
1083
|
shipping_status: 'unfulfilled',
|
|
498
|
-
customer_id:
|
|
1084
|
+
customer_id: 0,
|
|
499
1085
|
customer_name: '',
|
|
500
1086
|
country_calling_code: '',
|
|
501
1087
|
phone: '',
|
|
502
1088
|
email: '',
|
|
1089
|
+
customer: null,
|
|
503
1090
|
is_price_include_tax: 1,
|
|
504
1091
|
tax_title: '',
|
|
505
1092
|
tax_country_code: '',
|
|
@@ -512,18 +1099,21 @@ function createDefaultTempOrder(params) {
|
|
|
512
1099
|
surcharge_fee: '0.00',
|
|
513
1100
|
note: '',
|
|
514
1101
|
schedule_date: params.now,
|
|
515
|
-
created_at:
|
|
1102
|
+
created_at: undefined,
|
|
1103
|
+
request_unique_idempotency_token: '',
|
|
1104
|
+
vouchers: [],
|
|
516
1105
|
products: [],
|
|
517
1106
|
bookings: [],
|
|
518
1107
|
payments: [],
|
|
519
1108
|
surcharges: [],
|
|
520
|
-
discount_list: [],
|
|
521
1109
|
relation_forms: [],
|
|
522
1110
|
contacts: [],
|
|
523
|
-
contacts_info:
|
|
1111
|
+
contacts_info: null,
|
|
524
1112
|
holder: null,
|
|
525
|
-
|
|
526
|
-
|
|
1113
|
+
metadata: {},
|
|
1114
|
+
_extend: {
|
|
1115
|
+
productsByUid: {}
|
|
1116
|
+
}
|
|
527
1117
|
};
|
|
528
1118
|
}
|
|
529
1119
|
function buildSubmitPayload(params) {
|
|
@@ -535,51 +1125,52 @@ function buildSubmitPayload(params) {
|
|
|
535
1125
|
businessCode,
|
|
536
1126
|
channel,
|
|
537
1127
|
type,
|
|
1128
|
+
summary,
|
|
538
1129
|
enhance
|
|
539
1130
|
} = params;
|
|
540
1131
|
const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
|
|
541
|
-
const
|
|
542
|
-
const relationId = tempOrder.relation_id;
|
|
543
|
-
const tableFormId = tempOrder.table_form_id;
|
|
544
|
-
const bookingUuid = createUuidV4();
|
|
545
|
-
const bookingStart = (0, _dayjs.default)(now);
|
|
546
|
-
const bookingDuration = resolveTableOccupancyDuration(tempOrder);
|
|
547
|
-
const bookingEnd = bookingStart.add(bookingDuration, 'minute');
|
|
548
|
-
const bookings = relationId && tableFormId ? [{
|
|
549
|
-
relation_id: 0,
|
|
550
|
-
form_id: 0,
|
|
551
|
-
start_time: bookingStart.format('HH:mm'),
|
|
552
|
-
start_date: bookingStart.format('YYYY-MM-DD'),
|
|
553
|
-
end_time: bookingEnd.format('HH:mm'),
|
|
554
|
-
end_date: bookingEnd.format('YYYY-MM-DD'),
|
|
555
|
-
duration: bookingDuration,
|
|
556
|
-
metadata: {
|
|
557
|
-
unique_identification_number: bookingUuid,
|
|
558
|
-
collect_pax: resolveSubmitCollectPax(tempOrder)
|
|
559
|
-
},
|
|
560
|
-
select_date: bookingStart.format('YYYY-MM-DD'),
|
|
561
|
-
is_all: false,
|
|
562
|
-
like_status: 'common',
|
|
563
|
-
schedule_id: 0,
|
|
564
|
-
relation_type: '',
|
|
565
|
-
number: 1
|
|
566
|
-
}] : tempOrder.bookings || [];
|
|
567
|
-
const formRecordIds = relationId && tableFormId ? [{
|
|
568
|
-
form_id: tableFormId,
|
|
569
|
-
form_record_id: relationId
|
|
570
|
-
}] : undefined;
|
|
1132
|
+
const bookingUuid = (0, _orderCollectionIdentity.createUuidV4)();
|
|
571
1133
|
const {
|
|
572
|
-
|
|
1134
|
+
_extend: _extend,
|
|
1135
|
+
relation_id: _relationId,
|
|
1136
|
+
table_form_id: _tableFormId,
|
|
1137
|
+
resource_id: _resourceId,
|
|
573
1138
|
summary: _summary,
|
|
574
|
-
|
|
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,
|
|
575
1152
|
...tempOrderRest
|
|
576
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
|
+
}
|
|
577
1163
|
const payload = {
|
|
578
1164
|
...tempOrderRest,
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
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,
|
|
583
1174
|
sales_channel: tempOrder.sales_channel || 'my_pisel',
|
|
584
1175
|
order_sales_channel: channel ?? tempOrder.order_sales_channel ?? 'online_store',
|
|
585
1176
|
status: tempOrder.status || 'normal',
|
|
@@ -590,18 +1181,18 @@ function buildSubmitPayload(params) {
|
|
|
590
1181
|
is_deposit: tempOrder.is_deposit ?? 0,
|
|
591
1182
|
deposit_amount: tempOrder.deposit_amount || '0.00',
|
|
592
1183
|
shop_discount: tempOrder.shop_discount || '0.00',
|
|
593
|
-
surcharge_fee:
|
|
1184
|
+
surcharge_fee: tempOrder.surcharge_fee || '0.00',
|
|
594
1185
|
note: tempOrder.note || '',
|
|
1186
|
+
delivery_type: tempOrder.delivery_type || 'nil',
|
|
595
1187
|
schedule_date: scheduleDate,
|
|
596
|
-
|
|
1188
|
+
// created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
|
|
1189
|
+
bookings: (tempOrder.bookings || []).filter(booking => Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
|
|
597
1190
|
payments: tempOrder.payments || [],
|
|
598
|
-
// discount_list: tempOrder.discount_list || [],
|
|
599
1191
|
relation_forms: tempOrder.relation_forms || [],
|
|
600
|
-
form_record_ids: formRecordIds,
|
|
601
1192
|
// contacts: tempOrder.contacts || [],
|
|
602
|
-
contacts_info: tempOrder.contacts_info
|
|
1193
|
+
contacts_info: tempOrder.contacts_info && !Array.isArray(tempOrder.contacts_info) ? tempOrder.contacts_info : null,
|
|
603
1194
|
// holder: tempOrder.holder || null,
|
|
604
|
-
|
|
1195
|
+
summary: summary || tempOrder.summary || (0, _utils2.createEmptySummary)(),
|
|
605
1196
|
metadata: (() => {
|
|
606
1197
|
const {
|
|
607
1198
|
collect_pax: _collectPax,
|
|
@@ -614,23 +1205,96 @@ function buildSubmitPayload(params) {
|
|
|
614
1205
|
})(),
|
|
615
1206
|
products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product))
|
|
616
1207
|
};
|
|
617
|
-
|
|
1208
|
+
if (!enhance) return payload;
|
|
1209
|
+
const enhancedPayload = enhance(payload, {
|
|
618
1210
|
tempOrder,
|
|
619
1211
|
bookingUuid,
|
|
620
1212
|
now
|
|
621
|
-
})
|
|
1213
|
+
});
|
|
1214
|
+
return {
|
|
1215
|
+
...enhancedPayload,
|
|
1216
|
+
summary: enhancedPayload.summary ?? payload.summary
|
|
1217
|
+
};
|
|
622
1218
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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));
|
|
627
1292
|
}
|
|
628
1293
|
|
|
629
1294
|
/**
|
|
630
1295
|
* 历史 V1 加餐结构映射器。
|
|
631
1296
|
*
|
|
632
|
-
* @deprecated
|
|
633
|
-
* `ScanOrderSubmitProduct` 新结构(见 `OrderModule.submitTempOrder` 的加餐分支)。
|
|
1297
|
+
* @deprecated 标准 Sales checkout 已统一提交结构。
|
|
634
1298
|
* 本函数仅保留以兼容历史接入方,未来会移除。新代码请勿再调用。
|
|
635
1299
|
*/
|
|
636
1300
|
function formatV1Product(products) {
|
|
@@ -638,14 +1302,186 @@ function formatV1Product(products) {
|
|
|
638
1302
|
return {
|
|
639
1303
|
bundle: product.product_bundle,
|
|
640
1304
|
key: product.product_id,
|
|
641
|
-
option: product.
|
|
1305
|
+
option: product.product_sku?.option || [],
|
|
642
1306
|
product_id: product.product_id,
|
|
643
1307
|
product_variant_id: product.product_variant_id,
|
|
644
|
-
num: product.
|
|
1308
|
+
num: product.product_quantity,
|
|
645
1309
|
note: String(product.note ?? ''),
|
|
646
1310
|
rowKey: product.product_id,
|
|
647
1311
|
session: null,
|
|
648
|
-
unique: createUuidV4()
|
|
1312
|
+
unique: (0, _orderCollectionIdentity.createUuidV4)()
|
|
649
1313
|
};
|
|
650
1314
|
});
|
|
1315
|
+
}
|
|
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;
|
|
651
1487
|
}
|