@pisell/pisellos 0.0.568 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.js +10 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -3
- package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/dist/model/strategy/adapter/walletPass/evaluator.js +7 -5
- package/dist/model/strategy/adapter/walletPass/example.js +26 -3
- package/dist/model/strategy/adapter/walletPass/index.js +5 -5
- package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +24 -96
- package/dist/model/strategy/strategy-example.js +19 -5
- package/dist/modules/BaseModule.d.ts +2 -2
- package/dist/modules/BaseModule.js +12 -14
- package/dist/modules/BookingContext/index.d.ts +48 -0
- package/dist/modules/BookingContext/index.js +566 -0
- package/dist/modules/BookingContext/types.d.ts +102 -0
- package/dist/modules/BookingContext/types.js +51 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +302 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +149 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +249 -0
- package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/dist/modules/BookingContext/utils/flexible.js +56 -0
- package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
- package/dist/modules/BookingContext/utils/index.d.ts +11 -0
- package/dist/modules/BookingContext/utils/index.js +11 -0
- package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/dist/modules/BookingContext/utils/noResource.js +77 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
- package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/dist/modules/BookingContext/utils/productExtend.js +339 -0
- package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
- package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
- package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
- package/dist/modules/BookingContext/utils/resources.js +486 -0
- package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
- package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
- package/dist/modules/Cart/index.js +3 -0
- package/dist/modules/Cart/utils/cartProduct.js +27 -5
- package/dist/modules/Cart/utils/cartResource.js +0 -2
- package/dist/modules/Cart/utils/changePrice.js +11 -11
- package/dist/modules/Customer/index.d.ts +20 -0
- package/dist/modules/Customer/index.js +172 -83
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Date/index.js +5 -1
- package/dist/modules/Discount/index.d.ts +2 -2
- package/dist/modules/Discount/index.js +43 -30
- package/dist/modules/Discount/types.d.ts +1 -1
- package/dist/modules/OpenData/index.d.ts +8 -0
- package/dist/modules/OpenData/index.js +38 -16
- package/dist/modules/Order/index.d.ts +449 -24
- package/dist/modules/Order/index.js +5460 -574
- 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 +573 -746
- package/dist/modules/Payment/types.d.ts +44 -24
- package/dist/modules/Payment/utils.d.ts +1 -1
- package/dist/modules/Payment/utils.js +4 -3
- package/dist/modules/Payment/walletpass.d.ts +0 -2
- package/dist/modules/Payment/walletpass.js +49 -33
- package/dist/modules/Product/types.d.ts +29 -7
- package/dist/modules/ProductList/index.d.ts +17 -13
- package/dist/modules/ProductList/index.js +182 -81
- package/dist/modules/ProductList/types.d.ts +16 -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 +324 -513
- 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 +804 -165
- package/dist/modules/Schedule/getDateIsInSchedule.js +14 -12
- package/dist/modules/Schedule/index.d.ts +18 -5
- package/dist/modules/Schedule/index.js +79 -24
- package/dist/modules/Schedule/types.d.ts +2 -0
- package/dist/modules/Schedule/utils.js +1 -0
- package/dist/modules/Step/index.js +1 -0
- package/dist/modules/Summary/index.js +4 -3
- package/dist/modules/Summary/utils.js +22 -43
- package/dist/modules/SurchargeList/index.d.ts +18 -0
- package/dist/modules/SurchargeList/index.js +185 -0
- package/dist/modules/SurchargeList/types.d.ts +15 -0
- package/dist/modules/SurchargeList/types.js +1 -0
- package/dist/modules/index.d.ts +3 -0
- package/dist/modules/index.js +4 -1
- package/dist/plugins/app.d.ts +2 -0
- package/dist/plugins/request.d.ts +1 -0
- package/dist/plugins/request.js +4 -1
- package/dist/plugins/window.js +6 -2
- package/dist/server/index.d.ts +462 -8
- package/dist/server/index.js +6168 -680
- package/dist/server/modules/floor-plan/index.d.ts +39 -0
- package/dist/server/modules/floor-plan/index.js +595 -0
- package/dist/server/modules/floor-plan/types.d.ts +43 -0
- package/dist/server/modules/floor-plan/types.js +13 -0
- package/dist/server/modules/index.d.ts +7 -2
- package/dist/server/modules/index.js +6 -0
- package/dist/server/modules/menu/index.js +41 -32
- package/dist/server/modules/order/index.d.ts +207 -14
- package/dist/server/modules/order/index.js +2328 -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 +1416 -521
- 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 +298 -77
- package/dist/server/modules/resource/index.d.ts +2 -3
- package/dist/server/modules/resource/index.js +109 -86
- package/dist/server/modules/schedule/index.d.ts +6 -4
- package/dist/server/modules/schedule/index.js +145 -106
- package/dist/server/test.json +713 -0
- package/dist/server/types.d.ts +2 -0
- package/dist/server/utils/product.js +3 -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 +4009 -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/BookingByStep/index.js +60 -11
- package/dist/solution/BookingByStep/utils/capacity.js +11 -1
- package/dist/solution/BookingByStep/utils/resources.js +3 -1
- package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
- package/dist/solution/BookingTicket/index.d.ts +393 -24
- package/dist/solution/BookingTicket/index.js +2508 -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 +42 -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 +42 -28
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +30 -14
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
- package/dist/solution/BuyTickets/index.js +12 -9
- package/dist/solution/Checkout/index.d.ts +1 -0
- package/dist/solution/Checkout/index.js +275 -209
- package/dist/solution/Checkout/utils/index.js +20 -8
- package/dist/solution/RegisterAndLogin/config.js +2 -10
- package/dist/solution/RegisterAndLogin/index.js +76 -30
- 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 +519 -444
- 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 +18 -19
- package/dist/solution/ShopDiscount/types.d.ts +4 -5
- package/dist/solution/ShopDiscount/utils.d.ts +0 -9
- package/dist/solution/ShopDiscount/utils.js +0 -9
- 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 +32 -51
- package/dist/solution/VenueBooking/index.js +741 -808
- package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/dist/solution/VenueBooking/types.d.ts +1 -3
- package/dist/solution/VenueBooking/types.js +0 -1
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +9 -3
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
- package/dist/solution/index.d.ts +2 -0
- package/dist/solution/index.js +3 -1
- package/dist/types/index.d.ts +12 -2
- package/dist/utils/task.js +18 -15
- package/dist/utils/watch.js +1 -0
- package/lib/apis/picoding.js +0 -2
- package/lib/core/index.js +132 -130
- package/lib/effects/index.js +57 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +50 -92
- package/lib/model/index.js +21 -14
- package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
- package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
- package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
- package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
- package/lib/model/strategy/adapter/index.js +64 -100
- package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
- package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
- package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
- package/lib/model/strategy/adapter/itemRule/index.js +57 -83
- package/lib/model/strategy/adapter/itemRule/type.js +36 -97
- package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
- package/lib/model/strategy/adapter/promotion/evaluator.js +233 -382
- package/lib/model/strategy/adapter/promotion/examples.js +159 -139
- package/lib/model/strategy/adapter/promotion/index.js +0 -1
- package/lib/model/strategy/adapter/promotion/type.js +35 -199
- package/lib/model/strategy/adapter/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
- package/lib/model/strategy/adapter/walletPass/example.js +190 -217
- package/lib/model/strategy/adapter/walletPass/index.js +51 -75
- package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
- package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/lib/model/strategy/adapter/walletPass/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/lib/model/strategy/adapter/walletPass/utils.js +383 -676
- package/lib/model/strategy/engine.js +168 -270
- package/lib/model/strategy/index.js +34 -49
- package/lib/model/strategy/strategy-example.js +239 -243
- package/lib/model/strategy/type.js +40 -100
- package/lib/modules/Account/index.js +53 -39
- package/lib/modules/Account/types.js +33 -20
- package/lib/modules/AccountList/index.js +154 -116
- package/lib/modules/AccountList/types.js +31 -30
- package/lib/modules/AccountList/utils.js +30 -18
- package/lib/modules/BaseModule.d.ts +2 -2
- package/lib/modules/BaseModule.js +50 -29
- package/lib/modules/BookingContext/index.d.ts +48 -0
- package/lib/modules/BookingContext/index.js +368 -0
- package/lib/modules/BookingContext/types.d.ts +102 -0
- package/lib/modules/BookingContext/types.js +34 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +298 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +155 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +222 -0
- package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/lib/modules/BookingContext/utils/flexible.js +80 -0
- package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
- package/lib/modules/BookingContext/utils/index.d.ts +11 -0
- package/lib/modules/BookingContext/utils/index.js +43 -0
- package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/lib/modules/BookingContext/utils/noResource.js +90 -0
- package/lib/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +56 -0
- package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/lib/modules/BookingContext/utils/productExtend.js +283 -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 +46 -0
- package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
- package/lib/modules/BookingContext/utils/resources.js +377 -0
- package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
- package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
- package/lib/modules/Cart/index.js +124 -170
- package/lib/modules/Cart/types.js +51 -46
- package/lib/modules/Cart/utils/cartAccount.js +39 -40
- package/lib/modules/Cart/utils/cartDate.js +61 -56
- package/lib/modules/Cart/utils/cartDiscount.js +33 -28
- package/lib/modules/Cart/utils/cartNote.js +32 -27
- package/lib/modules/Cart/utils/cartProduct.js +261 -309
- package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
- package/lib/modules/Cart/utils/cartResource.js +78 -72
- package/lib/modules/Cart/utils/changePrice.js +59 -31
- package/lib/modules/Cart/utils/index.js +48 -106
- package/lib/modules/Customer/constants.js +34 -13
- package/lib/modules/Customer/index.d.ts +20 -0
- package/lib/modules/Customer/index.js +207 -217
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Customer/types.js +35 -38
- package/lib/modules/Date/index.js +115 -116
- package/lib/modules/Date/types.js +28 -16
- package/lib/modules/Date/utils.js +123 -174
- package/lib/modules/Discount/index.d.ts +2 -2
- package/lib/modules/Discount/index.js +133 -119
- package/lib/modules/Discount/types.d.ts +1 -1
- package/lib/modules/Discount/types.js +31 -9
- package/lib/modules/Guests/index.js +56 -30
- package/lib/modules/Guests/types.js +33 -23
- package/lib/modules/Holder/index.js +189 -209
- package/lib/modules/Holder/types.js +16 -4
- package/lib/modules/Holder/utils.js +49 -20
- package/lib/modules/OpenData/index.d.ts +8 -0
- package/lib/modules/OpenData/index.js +88 -63
- package/lib/modules/OpenData/types.js +16 -4
- package/lib/modules/OpenData/utils.js +78 -44
- package/lib/modules/Order/index.d.ts +449 -24
- package/lib/modules/Order/index.js +4184 -514
- package/lib/modules/Order/types.d.ts +693 -88
- package/lib/modules/Order/types.js +35 -24
- package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
- package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
- package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
- package/lib/modules/Order/utils/manualProductDiscount.js +206 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
- package/lib/modules/Order/utils.d.ts +167 -18
- package/lib/modules/Order/utils.js +1085 -414
- package/lib/modules/Payment/cash.js +33 -20
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
- package/lib/modules/Payment/eftpos.js +30 -16
- package/lib/modules/Payment/index.d.ts +10 -9
- package/lib/modules/Payment/index.js +402 -636
- package/lib/modules/Payment/mx51.js +0 -1
- package/lib/modules/Payment/types.d.ts +44 -24
- package/lib/modules/Payment/types.js +107 -216
- package/lib/modules/Payment/utils.d.ts +1 -1
- package/lib/modules/Payment/utils.js +50 -52
- package/lib/modules/Payment/walletpass.d.ts +0 -2
- package/lib/modules/Payment/walletpass.js +216 -221
- package/lib/modules/Product/index.js +46 -51
- package/lib/modules/Product/types.d.ts +29 -7
- package/lib/modules/Product/types.js +16 -4
- package/lib/modules/Product/utils.js +33 -32
- package/lib/modules/ProductList/index.d.ts +17 -13
- package/lib/modules/ProductList/index.js +161 -120
- package/lib/modules/ProductList/types.d.ts +16 -0
- package/lib/modules/ProductList/types.js +31 -9
- package/lib/modules/Quotation/index.d.ts +22 -2
- package/lib/modules/Quotation/index.js +154 -64
- package/lib/modules/Quotation/types.d.ts +19 -0
- package/lib/modules/Quotation/types.js +16 -4
- package/lib/modules/Resource/index.js +59 -27
- package/lib/modules/Resource/types.js +32 -22
- package/lib/modules/Resource/utils.js +38 -30
- package/lib/modules/ResourcePlanner/index.d.ts +24 -0
- package/lib/modules/ResourcePlanner/index.js +148 -0
- package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
- package/lib/modules/ResourcePlanner/planner.js +933 -0
- package/lib/modules/ResourcePlanner/types.d.ts +227 -0
- package/lib/modules/ResourcePlanner/types.js +17 -0
- package/lib/modules/Rules/index.d.ts +8 -10
- package/lib/modules/Rules/index.js +960 -1440
- package/lib/modules/Rules/types.d.ts +14 -3
- package/lib/modules/Rules/types.js +40 -17
- package/lib/modules/SalesSummary/index.d.ts +23 -26
- package/lib/modules/SalesSummary/index.js +134 -61
- package/lib/modules/SalesSummary/types.d.ts +9 -1
- package/lib/modules/SalesSummary/types.js +16 -4
- package/lib/modules/SalesSummary/utils.d.ts +3 -22
- package/lib/modules/SalesSummary/utils.js +814 -233
- package/lib/modules/ScanOrderLogger/index.js +79 -59
- package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
- package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
- package/lib/modules/ScanOrderLogger/types.js +16 -4
- package/lib/modules/Schedule/getDateIsInSchedule.js +169 -338
- package/lib/modules/Schedule/index.d.ts +18 -5
- package/lib/modules/Schedule/index.js +153 -104
- package/lib/modules/Schedule/type.js +16 -4
- package/lib/modules/Schedule/types.d.ts +2 -0
- package/lib/modules/Schedule/types.js +16 -4
- package/lib/modules/Schedule/utils.js +291 -433
- package/lib/modules/Step/index.js +52 -40
- package/lib/modules/Step/tyeps.js +16 -4
- package/lib/modules/Summary/index.js +71 -66
- package/lib/modules/Summary/types.js +16 -4
- package/lib/modules/Summary/utils.js +418 -791
- package/lib/modules/SurchargeList/index.d.ts +18 -0
- package/lib/modules/SurchargeList/index.js +109 -0
- package/lib/modules/SurchargeList/types.d.ts +15 -0
- package/lib/modules/SurchargeList/types.js +17 -0
- package/lib/modules/index.d.ts +3 -0
- package/lib/modules/index.js +63 -212
- package/lib/plugins/app.d.ts +2 -0
- package/lib/plugins/app.js +16 -4
- package/lib/plugins/index.js +25 -36
- package/lib/plugins/request.d.ts +1 -0
- package/lib/plugins/request.js +126 -137
- package/lib/plugins/shopStore.js +16 -4
- package/lib/plugins/user.js +16 -4
- package/lib/plugins/window.js +179 -171
- package/lib/server/index.d.ts +462 -8
- package/lib/server/index.js +4520 -1162
- package/lib/server/modules/floor-plan/index.d.ts +39 -0
- package/lib/server/modules/floor-plan/index.js +327 -0
- package/lib/server/modules/floor-plan/types.d.ts +43 -0
- package/lib/server/modules/floor-plan/types.js +34 -0
- package/lib/server/modules/index.d.ts +7 -2
- package/lib/server/modules/index.js +67 -84
- package/lib/server/modules/menu/index.js +122 -146
- package/lib/server/modules/menu/types.js +31 -18
- package/lib/server/modules/order/index.d.ts +207 -14
- package/lib/server/modules/order/index.js +1543 -285
- package/lib/server/modules/order/types.d.ts +76 -5
- package/lib/server/modules/order/types.js +32 -107
- package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
- package/lib/server/modules/order/utils/filterBookings.js +259 -176
- package/lib/server/modules/order/utils/filterOrders.js +293 -94
- package/lib/server/modules/payment/index.d.ts +28 -0
- package/lib/server/modules/payment/index.js +192 -0
- package/lib/server/modules/payment/types.d.ts +9 -0
- package/lib/server/modules/payment/types.js +17 -0
- package/lib/server/modules/products/index.d.ts +105 -14
- package/lib/server/modules/products/index.js +850 -475
- package/lib/server/modules/products/types.d.ts +34 -1
- package/lib/server/modules/products/types.js +34 -41
- package/lib/server/modules/quotation/index.d.ts +39 -0
- package/lib/server/modules/quotation/index.js +254 -75
- package/lib/server/modules/quotation/types.js +31 -21
- package/lib/server/modules/resource/index.d.ts +2 -3
- package/lib/server/modules/resource/index.js +240 -243
- package/lib/server/modules/resource/types.js +33 -42
- package/lib/server/modules/schedule/index.d.ts +6 -4
- package/lib/server/modules/schedule/index.js +146 -147
- package/lib/server/modules/schedule/types.js +21 -14
- package/lib/server/modules/schedule/utils.js +163 -334
- package/lib/server/test.json +713 -0
- package/lib/server/types.d.ts +2 -0
- package/lib/server/types.js +16 -4
- package/lib/server/utils/index.js +23 -25
- package/lib/server/utils/product.js +140 -197
- package/lib/server/utils/schedule.js +41 -34
- package/lib/server/utils/small-ticket.d.ts +71 -0
- package/lib/server/utils/small-ticket.js +904 -0
- package/lib/server/utils/time.js +49 -40
- package/lib/solution/BaseSales/index.d.ts +378 -0
- package/lib/solution/BaseSales/index.js +2533 -0
- package/lib/solution/BaseSales/types.d.ts +394 -0
- package/lib/solution/BaseSales/types.js +43 -0
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
- package/lib/solution/BaseSales/utils/cartPromotion.js +1004 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +144 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +160 -0
- package/lib/solution/BaseSales/utils/quotationPrice.d.ts +18 -0
- package/lib/solution/BaseSales/utils/quotationPrice.js +289 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +63 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +256 -0
- package/lib/solution/BaseSales/utils.d.ts +40 -0
- package/lib/solution/BaseSales/utils.js +244 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1340 -1530
- package/lib/solution/BookingByStep/types.js +99 -40
- package/lib/solution/BookingByStep/utils/capacity.js +160 -192
- package/lib/solution/BookingByStep/utils/products.js +52 -42
- package/lib/solution/BookingByStep/utils/resources.js +330 -527
- package/lib/solution/BookingByStep/utils/stock.js +44 -65
- package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
- package/lib/solution/BookingTicket/index.d.ts +393 -24
- package/lib/solution/BookingTicket/index.js +1374 -184
- package/lib/solution/BookingTicket/types.d.ts +191 -6
- package/lib/solution/BookingTicket/types.js +79 -40
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +117 -0
- package/lib/solution/BookingTicket/utils/addProductDecision.js +318 -0
- package/lib/solution/BookingTicket/utils/addTimeAvailability.d.ts +35 -0
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +125 -0
- package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +77 -0
- package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -0
- package/lib/solution/BookingTicket/utils/cartView.d.ts +29 -0
- package/lib/solution/BookingTicket/utils/cartView.js +184 -0
- package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
- package/lib/solution/BookingTicket/utils/exampleData.js +0 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/orderCustomer.js +58 -0
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts +185 -0
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +254 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +169 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.d.ts +4 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +97 -64
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
- package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -82
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +109 -91
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +127 -0
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +85 -0
- package/lib/solution/BuyTickets/index.js +70 -67
- package/lib/solution/BuyTickets/types.js +38 -22
- package/lib/solution/Checkout/index.d.ts +1 -0
- package/lib/solution/Checkout/index.js +1169 -1463
- package/lib/solution/Checkout/types.js +61 -91
- package/lib/solution/Checkout/utils/index.js +156 -228
- package/lib/solution/PlaceOrder/index.js +0 -55
- package/lib/solution/RegisterAndLogin/config.js +462 -503
- package/lib/solution/RegisterAndLogin/index.js +630 -633
- package/lib/solution/RegisterAndLogin/types.js +76 -189
- package/lib/solution/RegisterAndLogin/utils.js +125 -183
- package/lib/solution/Sales/index.d.ts +50 -5
- package/lib/solution/Sales/index.js +498 -238
- package/lib/solution/Sales/types.d.ts +26 -2
- package/lib/solution/Sales/types.js +33 -27
- package/lib/solution/ScanOrder/index.d.ts +27 -21
- package/lib/solution/ScanOrder/index.js +936 -864
- package/lib/solution/ScanOrder/types.d.ts +33 -11
- package/lib/solution/ScanOrder/types.js +34 -34
- package/lib/solution/ScanOrder/utils.d.ts +4 -1
- package/lib/solution/ScanOrder/utils.js +422 -385
- package/lib/solution/ShopDiscount/index.js +233 -235
- package/lib/solution/ShopDiscount/types.d.ts +4 -5
- package/lib/solution/ShopDiscount/types.js +37 -15
- package/lib/solution/ShopDiscount/utils.d.ts +0 -9
- package/lib/solution/ShopDiscount/utils.js +172 -309
- package/lib/solution/UnifiedBookingSales/index.d.ts +183 -0
- package/lib/solution/UnifiedBookingSales/index.js +1076 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +143 -0
- package/lib/solution/UnifiedBookingSales/types.js +33 -0
- package/lib/solution/VenueBooking/index.d.ts +32 -51
- package/lib/solution/VenueBooking/index.js +1008 -984
- package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/lib/solution/VenueBooking/types.d.ts +1 -3
- package/lib/solution/VenueBooking/types.js +39 -20
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
- package/lib/solution/VenueBooking/utils/resource.js +54 -31
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +109 -90
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
- package/lib/solution/VenueBooking/utils.js +67 -130
- package/lib/solution/index.d.ts +2 -0
- package/lib/solution/index.js +41 -102
- package/lib/store/createStore.js +29 -32
- package/lib/types/index.d.ts +12 -2
- package/lib/types/index.js +16 -4
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +47 -81
- package/package.json +2 -4
- package/dist/solution/Checkout/appointmentDemo.json +0 -1
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
- package/lib/solution/Checkout/appointmentDemo.json +0 -1
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
|
@@ -1,32 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.
|
|
4
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/modules/Rules/index.ts
|
|
30
|
+
var Rules_exports = {};
|
|
31
|
+
__export(Rules_exports, {
|
|
32
|
+
RulesModule: () => RulesModule
|
|
5
33
|
});
|
|
6
|
-
exports
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
defaultVersion = '1.0.0';
|
|
18
|
-
store;
|
|
19
|
-
window; // WindowPlugin 实例
|
|
20
|
-
hooks;
|
|
34
|
+
module.exports = __toCommonJS(Rules_exports);
|
|
35
|
+
var import_BaseModule = require("../BaseModule");
|
|
36
|
+
var import_types = require("./types");
|
|
37
|
+
var import_utils = require("../../solution/ShopDiscount/utils");
|
|
38
|
+
var import_utils2 = require("../Cart/utils");
|
|
39
|
+
var import_decimal = __toESM(require("decimal.js"));
|
|
40
|
+
var import_lodash_es = require("lodash-es");
|
|
41
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
42
|
+
var import_utils3 = require("../../solution/ShopDiscount/utils");
|
|
43
|
+
var import_utils4 = require("../../solution/ShopDiscount/utils");
|
|
44
|
+
var RulesModule = class extends import_BaseModule.BaseModule {
|
|
21
45
|
constructor(name, version) {
|
|
22
46
|
super(name, version);
|
|
47
|
+
this.defaultName = "rules";
|
|
48
|
+
this.defaultVersion = "1.0.0";
|
|
23
49
|
this.hooks = {};
|
|
24
50
|
}
|
|
25
51
|
async initialize(core, options) {
|
|
26
52
|
this.core = core;
|
|
27
|
-
this.hooks = options
|
|
28
|
-
this.store = options
|
|
29
|
-
this.window = core.getPlugin(
|
|
53
|
+
this.hooks = options == null ? void 0 : options.hooks;
|
|
54
|
+
this.store = options == null ? void 0 : options.store;
|
|
55
|
+
this.window = core.getPlugin("window");
|
|
30
56
|
}
|
|
31
57
|
async setRulesList(rulesList) {
|
|
32
58
|
this.store.rulesList = rulesList;
|
|
@@ -36,24 +62,22 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
36
62
|
return this.store.rulesList;
|
|
37
63
|
}
|
|
38
64
|
getWalletPassEvaluator() {
|
|
39
|
-
|
|
65
|
+
var _a, _b;
|
|
66
|
+
return (_b = (_a = this.window).getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
|
|
40
67
|
}
|
|
41
|
-
|
|
42
68
|
// 商品不需要holder,则不需要判断,直接返回true,商品需要holder但是还没填写,那么暂时不使用带有holder的券,直到填写才去匹配
|
|
43
69
|
checkHolderMatch(discount, product, holders) {
|
|
44
|
-
|
|
45
|
-
if (discount.holder
|
|
46
|
-
|
|
47
|
-
const orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id :
|
|
70
|
+
var _a;
|
|
71
|
+
if (((_a = discount.holder) == null ? void 0 : _a.holder_type) !== "form")
|
|
72
|
+
return true;
|
|
73
|
+
const orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id || holders[0] : void 0;
|
|
48
74
|
const productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// 最终直接匹配 holder 是否相同
|
|
75
|
+
if (!product.isNeedHolder)
|
|
76
|
+
return true;
|
|
77
|
+
if (!orderHolderId && !productHolderId)
|
|
78
|
+
return false;
|
|
54
79
|
return (productHolderId || orderHolderId) === discount.holder.holder_id;
|
|
55
80
|
}
|
|
56
|
-
|
|
57
81
|
// 判断discountList 是否可以对当前productList生效
|
|
58
82
|
isDiscountListAvailable({
|
|
59
83
|
oldDiscountList,
|
|
@@ -63,7 +87,6 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
63
87
|
holders,
|
|
64
88
|
isFormSubject
|
|
65
89
|
}) {
|
|
66
|
-
// 首先检查是否有新的优惠券可应用
|
|
67
90
|
if (!newDiscountList || newDiscountList.length === 0) {
|
|
68
91
|
return {
|
|
69
92
|
isAvailable: false,
|
|
@@ -71,58 +94,57 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
71
94
|
productList
|
|
72
95
|
};
|
|
73
96
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (productList.every(item => {
|
|
97
|
+
if (productList.every((item) => {
|
|
98
|
+
var _a;
|
|
77
99
|
const product = this.hooks.getProduct(item);
|
|
78
|
-
return product.booking_id && (product.discount_list
|
|
100
|
+
return product.booking_id && (((_a = product.discount_list) == null ? void 0 : _a.length) || product.total == 0);
|
|
79
101
|
})) {
|
|
80
102
|
return {
|
|
81
103
|
isAvailable: false,
|
|
82
104
|
discountList: oldDiscountList,
|
|
83
105
|
productList,
|
|
84
|
-
unavailableReason:
|
|
106
|
+
unavailableReason: import_types.UnavailableReason.AlreadyUsed
|
|
85
107
|
};
|
|
86
108
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
const filteredOldDiscountList = oldDiscountList.filter(
|
|
110
|
+
(discount) => !discount.isEditMode && (discount.tag !== "good_pass" || discount.isScan)
|
|
111
|
+
);
|
|
112
|
+
const mergedDiscountList = (0, import_utils.uniqueById)([
|
|
113
|
+
...filteredOldDiscountList,
|
|
114
|
+
...newDiscountList
|
|
115
|
+
]);
|
|
116
|
+
const result = this.calcDiscount(
|
|
117
|
+
{
|
|
118
|
+
discountList: mergedDiscountList,
|
|
119
|
+
productList: [...productList],
|
|
120
|
+
orderTotalAmount,
|
|
121
|
+
holders,
|
|
122
|
+
isFormSubject
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
scan: true
|
|
126
|
+
}
|
|
127
|
+
);
|
|
103
128
|
let hasApplicableDiscount = false;
|
|
104
|
-
const newDiscountIds = newDiscountList.map(discount => discount.id);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
discount_list
|
|
110
|
-
bundle
|
|
111
|
-
} = this.hooks.getProduct(product);
|
|
112
|
-
const allDiscountList = [...(discount_list || [])];
|
|
113
|
-
(bundle || []).forEach(item => {
|
|
114
|
-
allDiscountList.push(...(item?.discount_list || []));
|
|
129
|
+
const newDiscountIds = newDiscountList.map((discount) => discount.id);
|
|
130
|
+
result.productList.forEach((product) => {
|
|
131
|
+
const { discount_list, bundle } = this.hooks.getProduct(product);
|
|
132
|
+
const allDiscountList = [...discount_list || []];
|
|
133
|
+
(bundle || []).forEach((item) => {
|
|
134
|
+
allDiscountList.push(...(item == null ? void 0 : item.discount_list) || []);
|
|
115
135
|
});
|
|
116
136
|
if (allDiscountList && allDiscountList.length > 0) {
|
|
117
|
-
|
|
118
|
-
|
|
137
|
+
const usedNewDiscount = allDiscountList.some(
|
|
138
|
+
(discount) => {
|
|
139
|
+
var _a;
|
|
140
|
+
return newDiscountIds.includes((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id);
|
|
141
|
+
}
|
|
142
|
+
);
|
|
119
143
|
if (usedNewDiscount) {
|
|
120
144
|
hasApplicableDiscount = true;
|
|
121
145
|
}
|
|
122
146
|
}
|
|
123
147
|
});
|
|
124
|
-
|
|
125
|
-
// 如果券不可用,判断不可用原因
|
|
126
148
|
let unavailableReason;
|
|
127
149
|
if (!hasApplicableDiscount) {
|
|
128
150
|
unavailableReason = this.getUnavailableReason(newDiscountList, productList);
|
|
@@ -135,42 +157,47 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
135
157
|
};
|
|
136
158
|
}
|
|
137
159
|
filterDiscountListByType(discountList, type) {
|
|
138
|
-
return (discountList || []).filter(item => item.type === type || item.tag === type);
|
|
160
|
+
return (discountList || []).filter((item) => item.type === type || item.tag === type);
|
|
161
|
+
}
|
|
162
|
+
/** 剔除指定 type/tag 的折扣项,保留手动改价(type=product) / 券等 */
|
|
163
|
+
excludeDiscountListByType(discountList, type) {
|
|
164
|
+
return (discountList || []).filter((item) => item.type !== type && item.tag !== type);
|
|
165
|
+
}
|
|
166
|
+
/** 手动改价场景:去掉 promotion,保留 type=product 等行内折扣 */
|
|
167
|
+
resolveDiscountListForManualOverride(discountList) {
|
|
168
|
+
return this.excludeDiscountListByType(discountList, "promotion");
|
|
139
169
|
}
|
|
140
|
-
|
|
141
170
|
// 获取券不可用的原因
|
|
142
171
|
getUnavailableReason(discountList, productList) {
|
|
143
|
-
|
|
172
|
+
var _a;
|
|
144
173
|
for (const discount of discountList) {
|
|
145
174
|
for (const item of productList) {
|
|
146
175
|
const product = this.hooks.getProduct(item);
|
|
147
|
-
const bookingTime = (product
|
|
148
|
-
const filteredList = (0,
|
|
176
|
+
const bookingTime = ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss");
|
|
177
|
+
const filteredList = (0, import_utils.filterDiscountListByBookingTime)([discount], bookingTime);
|
|
149
178
|
if (filteredList.length === 0) {
|
|
150
|
-
return
|
|
179
|
+
return import_types.UnavailableReason.TimeLimit;
|
|
151
180
|
}
|
|
152
181
|
}
|
|
153
182
|
}
|
|
154
|
-
|
|
155
|
-
// 检查商品适用性
|
|
156
183
|
for (const discount of discountList) {
|
|
157
184
|
const limitedData = discount.limited_relation_product_data;
|
|
158
185
|
let hasApplicableProduct = false;
|
|
159
186
|
for (const item of productList) {
|
|
160
187
|
const product = this.hooks.getProduct(item);
|
|
161
|
-
if (limitedData.type ===
|
|
188
|
+
if (limitedData.type === "product_all") {
|
|
162
189
|
hasApplicableProduct = true;
|
|
163
190
|
break;
|
|
164
|
-
} else if (limitedData.product_ids
|
|
191
|
+
} else if ((_a = limitedData.product_ids) == null ? void 0 : _a.includes(product.id)) {
|
|
165
192
|
hasApplicableProduct = true;
|
|
166
193
|
break;
|
|
167
194
|
}
|
|
168
195
|
}
|
|
169
196
|
if (!hasApplicableProduct) {
|
|
170
|
-
return
|
|
197
|
+
return import_types.UnavailableReason.ProductNotApplicable;
|
|
171
198
|
}
|
|
172
199
|
}
|
|
173
|
-
return
|
|
200
|
+
return import_types.UnavailableReason.Unknown;
|
|
174
201
|
}
|
|
175
202
|
calcDiscount({
|
|
176
203
|
discountList,
|
|
@@ -179,47 +206,83 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
179
206
|
isFormSubject,
|
|
180
207
|
orderTotalAmount
|
|
181
208
|
}, options) {
|
|
209
|
+
var _a;
|
|
210
|
+
const resolveIsFormSubject = (product) => typeof isFormSubject === "function" ? Boolean(isFormSubject(product)) : Boolean(isFormSubject);
|
|
211
|
+
const isEditModeAddNewProduct = productList.find((n) => n.booking_id) && productList.find((n) => !n.booking_id);
|
|
212
|
+
const reapplyBookingDiscountProductUids = new Set(
|
|
213
|
+
((options == null ? void 0 : options.reapplyBookingDiscountProductUids) || []).filter((uid) => uid !== void 0 && uid !== null && uid !== "").map(String)
|
|
214
|
+
);
|
|
215
|
+
const getOriginProductUid = (originProduct) => {
|
|
216
|
+
var _a2;
|
|
217
|
+
const uid = ((_a2 = originProduct == null ? void 0 : originProduct.metadata) == null ? void 0 : _a2.unique_identification_number) ?? (originProduct == null ? void 0 : originProduct.unique_identification_number);
|
|
218
|
+
if (uid === void 0 || uid === null || uid === "")
|
|
219
|
+
return void 0;
|
|
220
|
+
return String(uid);
|
|
221
|
+
};
|
|
222
|
+
const shouldReapplyBookingDiscount = (originProduct, selectedDiscount) => {
|
|
223
|
+
if (!selectedDiscount)
|
|
224
|
+
return false;
|
|
225
|
+
const uid = getOriginProductUid(originProduct);
|
|
226
|
+
if (!uid || !reapplyBookingDiscountProductUids.has(uid))
|
|
227
|
+
return false;
|
|
228
|
+
const discountType = selectedDiscount.tag || selectedDiscount.type;
|
|
229
|
+
return selectedDiscount.isEditMode === true && selectedDiscount.isSelected === true && ["good_pass", "discount_card", "product_discount_card"].includes(discountType);
|
|
230
|
+
};
|
|
231
|
+
const resolveReapplyEditModeDiscountPercent = (originProduct, selectedDiscount) => {
|
|
232
|
+
var _a2;
|
|
233
|
+
if (!shouldReapplyBookingDiscount(originProduct, selectedDiscount))
|
|
234
|
+
return void 0;
|
|
235
|
+
const discountType = (selectedDiscount == null ? void 0 : selectedDiscount.tag) || (selectedDiscount == null ? void 0 : selectedDiscount.type);
|
|
236
|
+
if (discountType !== "discount_card" && discountType !== "product_discount_card") {
|
|
237
|
+
return void 0;
|
|
238
|
+
}
|
|
239
|
+
const percent = Number((_a2 = selectedDiscount.discount) == null ? void 0 : _a2.percent);
|
|
240
|
+
return Number.isFinite(percent) ? percent : void 0;
|
|
241
|
+
};
|
|
182
242
|
const editModeDiscount = [];
|
|
183
243
|
const addModeDiscount = [];
|
|
184
|
-
discountList.forEach(discount => {
|
|
244
|
+
discountList.forEach((discount) => {
|
|
185
245
|
if (discount.isEditMode) {
|
|
186
246
|
editModeDiscount.push(discount);
|
|
187
247
|
} else {
|
|
188
248
|
addModeDiscount.push(discount);
|
|
189
249
|
}
|
|
190
250
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
editModeOrderLevelProductIds.add(discount?.discount?.discount_product_id);
|
|
251
|
+
const editModeOrderLevelProductIds = /* @__PURE__ */ new Set();
|
|
252
|
+
editModeDiscount.forEach((discount) => {
|
|
253
|
+
var _a2, _b;
|
|
254
|
+
if (((_a2 = discount.discount) == null ? void 0 : _a2.discount_calculation_mode) === "order_level") {
|
|
255
|
+
editModeOrderLevelProductIds.add((_b = discount == null ? void 0 : discount.discount) == null ? void 0 : _b.discount_product_id);
|
|
197
256
|
}
|
|
198
257
|
});
|
|
199
|
-
|
|
200
|
-
// 如果存在订单级别的编辑模式折扣,禁用 addModeDiscount 中相同 product_id 的折扣卡
|
|
201
258
|
if (editModeOrderLevelProductIds.size > 0) {
|
|
202
|
-
addModeDiscount.forEach(discount => {
|
|
259
|
+
addModeDiscount.forEach((discount) => {
|
|
203
260
|
if (editModeOrderLevelProductIds.has(discount.product_id)) {
|
|
204
261
|
discount.isDisabled = true;
|
|
205
262
|
}
|
|
206
263
|
});
|
|
207
264
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
265
|
+
const hasDiscountInput = editModeDiscount.length > 0 || addModeDiscount.length > 0 || Boolean(options == null ? void 0 : options.discountId) || Boolean((_a = options == null ? void 0 : options.selectedList) == null ? void 0 : _a.length) || Boolean(options == null ? void 0 : options.scan);
|
|
266
|
+
if (!hasDiscountInput) {
|
|
267
|
+
return {
|
|
268
|
+
discountList,
|
|
269
|
+
productList
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const canUseEditModeDiscountForReapply = (discount) => {
|
|
273
|
+
const discountType = discount.tag || discount.type;
|
|
274
|
+
return reapplyBookingDiscountProductUids.size > 0 && discount.isEditMode === true && discount.isSelected === true && ["good_pass", "discount_card", "product_discount_card"].includes(discountType);
|
|
275
|
+
};
|
|
276
|
+
const filteredDiscountList = [
|
|
277
|
+
...addModeDiscount.filter((discount) => !discount.isManualSelect),
|
|
278
|
+
...editModeDiscount.filter(canUseEditModeDiscountForReapply)
|
|
279
|
+
];
|
|
280
|
+
const flattenProductsWithBundle = (productList2) => {
|
|
216
281
|
const flattened = [];
|
|
217
|
-
|
|
282
|
+
productList2.forEach((originProduct) => {
|
|
218
283
|
const product = this.hooks.getProduct(originProduct);
|
|
219
|
-
|
|
220
|
-
// 1. 添加主商品
|
|
221
284
|
flattened.push({
|
|
222
|
-
type:
|
|
285
|
+
type: "main",
|
|
223
286
|
originProduct,
|
|
224
287
|
product,
|
|
225
288
|
price: Number(product.price || 0),
|
|
@@ -230,12 +293,10 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
230
293
|
num: product.num,
|
|
231
294
|
booking_id: product.booking_id
|
|
232
295
|
});
|
|
233
|
-
|
|
234
|
-
// 2. 展开 bundle 子商品
|
|
235
296
|
if (product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0) {
|
|
236
297
|
product.bundle.forEach((bundleItem, bundleIndex) => {
|
|
237
298
|
flattened.push({
|
|
238
|
-
type:
|
|
299
|
+
type: "bundle",
|
|
239
300
|
originProduct,
|
|
240
301
|
parentProduct: product,
|
|
241
302
|
bundleItem,
|
|
@@ -248,8 +309,8 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
248
309
|
parentId: product._id,
|
|
249
310
|
num: bundleItem.num || 1,
|
|
250
311
|
quantity: bundleItem.num || 1,
|
|
251
|
-
total: new
|
|
252
|
-
origin_total: new
|
|
312
|
+
total: new import_decimal.default(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
|
|
313
|
+
origin_total: new import_decimal.default(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
|
|
253
314
|
original_price: bundleItem.original_price,
|
|
254
315
|
// 继承主商品属性
|
|
255
316
|
booking_id: bundleItem.booking_id,
|
|
@@ -260,161 +321,120 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
260
321
|
});
|
|
261
322
|
return flattened;
|
|
262
323
|
};
|
|
263
|
-
|
|
264
|
-
// 优惠力度排序,传进来的数据里可能有商品券,也可能有优惠券
|
|
265
|
-
// 新的优先级排序规则(从高到低):
|
|
266
|
-
// 1. 带有Holder的商品券(metadata?.holder?.type === 'custom' && tag === 'good_pass')
|
|
267
|
-
// 2. 带有Holder的商品级折扣卡(metadata?.holder?.type === 'custom' && tag === 'product_discount_card' && discount_calculation_mode !== 'order_level')
|
|
268
|
-
// 3. 带有Holder的订单级折扣卡(metadata?.holder?.type === 'custom' && tag === 'product_discount_card' && discount_calculation_mode === 'order_level')
|
|
269
|
-
// 4. Customer商品券(metadata?.holder?.type !== 'custom' && tag === 'good_pass')
|
|
270
|
-
// 5. Customer商品级折扣卡(metadata?.holder?.type !== 'custom' && tag === 'product_discount_card' && discount_calculation_mode !== 'order_level')
|
|
271
|
-
// 6. Customer订单级固定金额折扣(metadata?.holder?.type !== 'custom' && tag === 'product_discount_card' && discount_calculation_mode === 'order_level')
|
|
272
|
-
// 同一优先级内部:固定金额优先于百分比,金额/折扣力度越大越优先,最后按过期时间排序
|
|
273
324
|
const sortedDiscountList = [...filteredDiscountList].sort((a, b) => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const isGoodPass = discount => discount.tag ===
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const getPriority = discount => {
|
|
325
|
+
const isHolderDiscount = (discount) => {
|
|
326
|
+
var _a2, _b;
|
|
327
|
+
return ((_b = (_a2 = discount.metadata) == null ? void 0 : _a2.holder) == null ? void 0 : _b.type) === "custom";
|
|
328
|
+
};
|
|
329
|
+
const isGoodPass = (discount) => discount.tag === "good_pass";
|
|
330
|
+
const isOrderLevelDiscount = (discount) => {
|
|
331
|
+
var _a2;
|
|
332
|
+
return discount.tag === "product_discount_card" && ((_a2 = discount.metadata) == null ? void 0 : _a2.discount_calculation_mode) === "order_level";
|
|
333
|
+
};
|
|
334
|
+
const isItemLevelDiscount = (discount) => {
|
|
335
|
+
var _a2;
|
|
336
|
+
return discount.tag === "product_discount_card" && ((_a2 = discount.metadata) == null ? void 0 : _a2.discount_calculation_mode) !== "order_level";
|
|
337
|
+
};
|
|
338
|
+
const getPriority = (discount) => {
|
|
288
339
|
const isHolder = isHolderDiscount(discount);
|
|
289
340
|
if (isHolder) {
|
|
290
|
-
if (isGoodPass(discount))
|
|
291
|
-
|
|
292
|
-
if (
|
|
341
|
+
if (isGoodPass(discount))
|
|
342
|
+
return 1;
|
|
343
|
+
if (isItemLevelDiscount(discount))
|
|
344
|
+
return 2;
|
|
345
|
+
if (isOrderLevelDiscount(discount))
|
|
346
|
+
return 3;
|
|
293
347
|
} else {
|
|
294
|
-
if (isGoodPass(discount))
|
|
295
|
-
|
|
296
|
-
if (
|
|
348
|
+
if (isGoodPass(discount))
|
|
349
|
+
return 4;
|
|
350
|
+
if (isItemLevelDiscount(discount))
|
|
351
|
+
return 5;
|
|
352
|
+
if (isOrderLevelDiscount(discount))
|
|
353
|
+
return 6;
|
|
297
354
|
}
|
|
298
|
-
return 7;
|
|
355
|
+
return 7;
|
|
299
356
|
};
|
|
300
|
-
|
|
301
|
-
// 辅助函数:按过期时间比较
|
|
302
357
|
function compareByExpireTime(itemA, itemB) {
|
|
303
358
|
if (itemA.expire_time && itemB.expire_time) {
|
|
304
359
|
const timeA = new Date(itemA.expire_time).getTime();
|
|
305
360
|
const timeB = new Date(itemB.expire_time).getTime();
|
|
306
361
|
return timeA - timeB;
|
|
307
362
|
}
|
|
308
|
-
// 有过期时间的优先级高于永久的
|
|
309
363
|
return itemA.expire_time ? -1 : itemB.expire_time ? 1 : 0;
|
|
310
364
|
}
|
|
311
|
-
|
|
312
|
-
// 辅助函数:同类型折扣卡内部排序(固定金额优先于百分比,金额/折扣力度排序)
|
|
313
365
|
function compareDiscountCardValue(itemA, itemB) {
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (typeA ===
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (typeA === 'fixed_amount' && typeB === 'fixed_amount') {
|
|
366
|
+
var _a2, _b;
|
|
367
|
+
const typeA = ((_a2 = itemA.metadata) == null ? void 0 : _a2.discount_card_type) || "percent";
|
|
368
|
+
const typeB = ((_b = itemB.metadata) == null ? void 0 : _b.discount_card_type) || "percent";
|
|
369
|
+
if (typeA === "fixed_amount" && typeB === "percent")
|
|
370
|
+
return -1;
|
|
371
|
+
if (typeA === "percent" && typeB === "fixed_amount")
|
|
372
|
+
return 1;
|
|
373
|
+
if (typeA === "fixed_amount" && typeB === "fixed_amount") {
|
|
323
374
|
if (itemA.par_value !== itemB.par_value) {
|
|
324
|
-
const valueA = new
|
|
325
|
-
const valueB = new
|
|
326
|
-
return valueB.minus(valueA).toNumber();
|
|
375
|
+
const valueA = new import_decimal.default(itemA.par_value || 0);
|
|
376
|
+
const valueB = new import_decimal.default(itemB.par_value || 0);
|
|
377
|
+
return valueB.minus(valueA).toNumber();
|
|
327
378
|
}
|
|
328
379
|
}
|
|
329
|
-
|
|
330
|
-
// 3. 都是百分比时,折扣越大越优先(par_value越大越优先)
|
|
331
|
-
if (typeA === 'percent' && typeB === 'percent') {
|
|
380
|
+
if (typeA === "percent" && typeB === "percent") {
|
|
332
381
|
if (itemA.par_value !== itemB.par_value) {
|
|
333
|
-
const valueA = new
|
|
334
|
-
const valueB = new
|
|
335
|
-
return valueA.minus(valueB).toNumber();
|
|
382
|
+
const valueA = new import_decimal.default(100).minus(itemA.par_value || 0);
|
|
383
|
+
const valueB = new import_decimal.default(100).minus(itemB.par_value || 0);
|
|
384
|
+
return valueA.minus(valueB).toNumber();
|
|
336
385
|
}
|
|
337
386
|
}
|
|
338
387
|
return 0;
|
|
339
388
|
}
|
|
340
|
-
|
|
341
|
-
// 1. 先按优先级排序
|
|
342
389
|
const priorityA = getPriority(a);
|
|
343
390
|
const priorityB = getPriority(b);
|
|
344
391
|
if (priorityA !== priorityB) {
|
|
345
392
|
return priorityA - priorityB;
|
|
346
393
|
}
|
|
347
|
-
|
|
348
|
-
// 2. 同一优先级内部排序
|
|
349
|
-
// 如果是商品券(优先级1或4),按过期时间排序
|
|
350
394
|
if (isGoodPass(a) && isGoodPass(b)) {
|
|
351
395
|
return compareByExpireTime(a, b);
|
|
352
396
|
}
|
|
353
|
-
|
|
354
|
-
// 如果是折扣卡(优先级2、3、5、6),按折扣力度排序,然后按过期时间
|
|
355
|
-
if (a.tag === 'product_discount_card' && b.tag === 'product_discount_card') {
|
|
397
|
+
if (a.tag === "product_discount_card" && b.tag === "product_discount_card") {
|
|
356
398
|
const valueCompare = compareDiscountCardValue(a, b);
|
|
357
|
-
if (valueCompare !== 0)
|
|
399
|
+
if (valueCompare !== 0)
|
|
400
|
+
return valueCompare;
|
|
358
401
|
return compareByExpireTime(a, b);
|
|
359
402
|
}
|
|
360
|
-
|
|
361
|
-
// 3. 其他情况按照过期时间排序
|
|
362
403
|
return compareByExpireTime(a, b);
|
|
363
404
|
});
|
|
364
|
-
|
|
365
|
-
// const newProductList = [];
|
|
366
|
-
//
|
|
367
|
-
// productList.forEach(item => {
|
|
368
|
-
// const product = this.hooks.getProduct(item);
|
|
369
|
-
// if (product.quantity > 1) {
|
|
370
|
-
// for (let i = 1; i < product.quantity; i++) {
|
|
371
|
-
// newProductList.push(product)
|
|
372
|
-
// }
|
|
373
|
-
// } else {
|
|
374
|
-
// newProductList.push(item)
|
|
375
|
-
// }
|
|
376
|
-
// })
|
|
377
|
-
|
|
378
|
-
// 🔥 扁平化商品列表(包含主商品和bundle子商品)
|
|
379
405
|
const flattenedList = flattenProductsWithBundle(productList);
|
|
380
|
-
|
|
381
|
-
// 识别出来是不是在编辑的界面里又新增了商品
|
|
382
|
-
// 这种情况下,如果有可用的优惠券,也会自动勾选上
|
|
383
|
-
const isEditModeAddNewProduct = flattenedList.find(n => n.booking_id) && flattenedList.find(n => !n.booking_id);
|
|
384
|
-
|
|
385
|
-
// 对扁平化后的列表按价格降序排序(用于应用优惠券时优先选择高价商品)
|
|
386
406
|
const sortedFlattenedList = flattenedList.sort((a, b) => {
|
|
387
|
-
|
|
388
|
-
const priceA = new
|
|
389
|
-
|
|
407
|
+
var _a2, _b;
|
|
408
|
+
const priceA = new import_decimal.default(
|
|
409
|
+
a.type === "bundle" ? a.original_price ?? a.price ?? "0" : a.price || "0"
|
|
410
|
+
);
|
|
411
|
+
const priceB = new import_decimal.default(
|
|
412
|
+
b.type === "bundle" ? b.original_price ?? b.price ?? "0" : b.price || "0"
|
|
413
|
+
);
|
|
390
414
|
if (priceA.equals(priceB)) {
|
|
391
|
-
// 价格相同时,主商品优先
|
|
392
415
|
if (a.type !== b.type) {
|
|
393
|
-
return a.type ===
|
|
416
|
+
return a.type === "main" ? -1 : 1;
|
|
394
417
|
}
|
|
395
|
-
|
|
396
|
-
if (a.type === 'main' && b.type === 'main') {
|
|
418
|
+
if (a.type === "main" && b.type === "main") {
|
|
397
419
|
if (a.product.quantity === b.product.quantity) {
|
|
398
|
-
return (b.product.discount_list
|
|
420
|
+
return (((_a2 = b.product.discount_list) == null ? void 0 : _a2.length) || 0) - (((_b = a.product.discount_list) == null ? void 0 : _b.length) || 0);
|
|
399
421
|
}
|
|
400
422
|
return a.product.quantity - b.product.quantity;
|
|
401
423
|
}
|
|
402
|
-
|
|
403
|
-
if (a.type === 'bundle' && b.type === 'bundle') {
|
|
424
|
+
if (a.type === "bundle" && b.type === "bundle") {
|
|
404
425
|
return (a.num || 1) - (b.num || 1);
|
|
405
426
|
}
|
|
406
427
|
}
|
|
407
428
|
return priceB.minus(priceA).toNumber();
|
|
408
429
|
});
|
|
409
|
-
|
|
410
|
-
// 🔥 为每个折扣卡/商品券执行策略检查并附加config
|
|
411
430
|
const evaluator = this.getWalletPassEvaluator();
|
|
412
431
|
if (evaluator) {
|
|
413
|
-
addModeDiscount.forEach(discount => {
|
|
432
|
+
addModeDiscount.forEach((discount) => {
|
|
433
|
+
var _a2, _b;
|
|
414
434
|
const discountType = discount.tag || discount.type;
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
435
|
+
if (["good_pass", "discount_card", "product_discount_card"].includes(
|
|
436
|
+
discountType
|
|
437
|
+
)) {
|
|
418
438
|
const voucher = {
|
|
419
439
|
id: discount.id,
|
|
420
440
|
amount: Number(discount.par_value || 0),
|
|
@@ -422,27 +442,24 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
422
442
|
type: discountType,
|
|
423
443
|
product_id: discount.product_id,
|
|
424
444
|
unified_available_status: 1,
|
|
425
|
-
available_product_type: discount.limited_relation_product_data
|
|
426
|
-
available_product_ids: discount.limited_relation_product_data
|
|
445
|
+
available_product_type: (_a2 = discount.limited_relation_product_data) == null ? void 0 : _a2.type,
|
|
446
|
+
available_product_ids: (_b = discount.limited_relation_product_data) == null ? void 0 : _b.product_ids
|
|
427
447
|
};
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
// 调用策略检查
|
|
448
|
+
const productsForEvaluate = sortedFlattenedList.map((item) => {
|
|
449
|
+
var _a3;
|
|
450
|
+
return {
|
|
451
|
+
product_id: item.id,
|
|
452
|
+
price: item.price || 0,
|
|
453
|
+
quantity: item.quantity || item.num || 1,
|
|
454
|
+
selling_price: item.price || 0,
|
|
455
|
+
product_options: item.type === "main" ? (_a3 = item.product) == null ? void 0 : _a3.options : void 0
|
|
456
|
+
};
|
|
457
|
+
});
|
|
439
458
|
const result = evaluator.checkVoucherAvailability({
|
|
440
|
-
orderTotalAmount
|
|
459
|
+
orderTotalAmount,
|
|
441
460
|
products: productsForEvaluate,
|
|
442
461
|
vouchers: [voucher]
|
|
443
462
|
});
|
|
444
|
-
|
|
445
|
-
// 将 config 附加到 discount 对象
|
|
446
463
|
if (result.isAvailable) {
|
|
447
464
|
discount.config = {
|
|
448
465
|
...result.config,
|
|
@@ -456,74 +473,21 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
456
473
|
}
|
|
457
474
|
});
|
|
458
475
|
}
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
// 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
|
|
468
|
-
const sortedProductList = [...productList].sort((a, b) => {
|
|
469
|
-
const aProduct = this.hooks.getProduct(a);
|
|
470
|
-
const bProduct = this.hooks.getProduct(b);
|
|
471
|
-
const priceA = new Decimal((aProduct.price as string) || '0');
|
|
472
|
-
const priceB = new Decimal((bProduct.price as string) || '0');
|
|
473
|
-
if (priceA.toNumber() === priceB.toNumber()) {
|
|
474
|
-
if (aProduct.quantity === bProduct.quantity) {
|
|
475
|
-
return bProduct.discount_list?.length - aProduct.discount_list?.length;
|
|
476
|
-
}
|
|
477
|
-
return aProduct.quantity - bProduct.quantity;
|
|
478
|
-
}
|
|
479
|
-
return priceB.toNumber() - priceA.toNumber();
|
|
480
|
-
});
|
|
481
|
-
*/
|
|
482
|
-
|
|
483
|
-
// 标记已使用的优惠券
|
|
484
|
-
const usedDiscounts = new Map();
|
|
485
|
-
|
|
486
|
-
// 🔥 统计每个 product_id(商品券商品id)已使用的数量,用于 maxUsagePerOrder 限制
|
|
487
|
-
const usedProductIdCounts = new Map();
|
|
488
|
-
|
|
489
|
-
// 🔥 统计每张折扣卡的 applicableProductLimit 已使用次数(跨商品全局计数)
|
|
490
|
-
const usedDiscountCardLimitCounts = new Map();
|
|
491
|
-
|
|
492
|
-
// 🔥 预先将 editModeDiscount 中的折扣卡计入 applicableProductLimit 已使用次数
|
|
493
|
-
editModeDiscount.forEach(discount => {
|
|
494
|
-
const discountType = discount.tag || discount.type;
|
|
495
|
-
if (['discount_card', 'product_discount_card'].includes(discountType)) {
|
|
496
|
-
const currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
|
|
497
|
-
usedDiscountCardLimitCounts.set(discount.id, currentCount + (discount.metadata?.num || 1));
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
// 记录每个优惠券适用的商品ID
|
|
502
|
-
const discountApplicability = new Map();
|
|
503
|
-
|
|
504
|
-
// 记录每个优惠券适用的商品详细信息
|
|
505
|
-
const discountApplicableProducts = new Map();
|
|
506
|
-
|
|
507
|
-
// 初始化每个优惠券的适用性和可抵扣商品
|
|
508
|
-
addModeDiscount.forEach(discount => {
|
|
476
|
+
const usedDiscounts = /* @__PURE__ */ new Map();
|
|
477
|
+
const usedProductIdCounts = /* @__PURE__ */ new Map();
|
|
478
|
+
const discountApplicability = /* @__PURE__ */ new Map();
|
|
479
|
+
const discountApplicableProducts = /* @__PURE__ */ new Map();
|
|
480
|
+
addModeDiscount.forEach((discount) => {
|
|
509
481
|
discountApplicability.set(discount.id, []);
|
|
510
482
|
discountApplicableProducts.set(discount.id, []);
|
|
511
483
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const orderLevelDiscountAllocations = new Map();
|
|
516
|
-
|
|
517
|
-
// 第一步:收集所有被勾选的 order_level 折扣卡及其适用商品
|
|
518
|
-
// Map<discountId, Set<flatItemId>> - 记录每个折扣卡适用的商品
|
|
519
|
-
const orderLevelDiscountApplicableItems = new Map();
|
|
520
|
-
// Map<flatItemId, Set<discountId>> - 记录每个商品可以被哪些折扣卡使用
|
|
521
|
-
const itemApplicableDiscounts = new Map();
|
|
522
|
-
|
|
523
|
-
// 辅助函数:检查商品是否对某个折扣卡可用
|
|
484
|
+
const orderLevelDiscountAllocations = /* @__PURE__ */ new Map();
|
|
485
|
+
const orderLevelDiscountApplicableItems = /* @__PURE__ */ new Map();
|
|
486
|
+
const itemApplicableDiscounts = /* @__PURE__ */ new Map();
|
|
524
487
|
const checkItemApplicableForDiscount = (flatItem, discount) => {
|
|
488
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
525
489
|
let product;
|
|
526
|
-
if (flatItem.type ===
|
|
490
|
+
if (flatItem.type === "main") {
|
|
527
491
|
product = flatItem.product;
|
|
528
492
|
} else {
|
|
529
493
|
product = {
|
|
@@ -534,38 +498,27 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
534
498
|
num: flatItem.num,
|
|
535
499
|
booking_id: flatItem.booking_id,
|
|
536
500
|
discount_list: flatItem.discount_list || [],
|
|
537
|
-
startDate: flatItem.parentProduct
|
|
501
|
+
startDate: (_a2 = flatItem.parentProduct) == null ? void 0 : _a2.startDate
|
|
538
502
|
};
|
|
539
503
|
}
|
|
540
|
-
|
|
541
|
-
// 编辑的商品使用了优惠券不可用
|
|
542
|
-
const isAvailableProduct = flatItem.type === 'main' ? !(product?.booking_id && product?.discount_list?.length && product?.discount_list?.every(d => d.id && ['good_pass', 'discount_card', 'product_discount_card'].includes(d.tag || d.type))) : !(flatItem?.booking_id && !!flatItem?.bundleItem?.discount_list?.length && flatItem?.bundleItem?.discount_list?.every(d => d.id));
|
|
504
|
+
const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.length) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.every((d) => d.id && ["good_pass", "discount_card", "product_discount_card"].includes(d.tag || d.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_e = (_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) == null ? void 0 : _e.length) && ((_g = (_f = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _f.discount_list) == null ? void 0 : _g.every((d) => d.id)));
|
|
543
505
|
if (!isAvailableProduct) {
|
|
544
506
|
return false;
|
|
545
507
|
}
|
|
546
|
-
|
|
547
|
-
// vouchersApplicable 为 false 的商品不参与订单级别折扣均摊
|
|
548
|
-
if ((0, _lodashEs.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
508
|
+
if ((0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
549
509
|
return false;
|
|
550
510
|
}
|
|
551
|
-
|
|
552
|
-
// 商品价格为0时不可用
|
|
553
511
|
if (Number(product.price) <= 0 || !product.price) {
|
|
554
512
|
return false;
|
|
555
513
|
}
|
|
556
514
|
const limitedData = discount.limited_relation_product_data;
|
|
557
|
-
|
|
558
|
-
// 时间限制检查
|
|
559
|
-
const timeLimit = !!(0, _utils.filterDiscountListByBookingTime)([discount], (product?.startDate || (0, _dayjs.default)()).format('YYYY-MM-DD HH:mm:ss')).length;
|
|
515
|
+
const timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
|
|
560
516
|
if (!timeLimit) {
|
|
561
517
|
return false;
|
|
562
518
|
}
|
|
563
|
-
|
|
564
|
-
// 判断商品是否适用
|
|
565
519
|
let isLimitedProduct = false;
|
|
566
|
-
if (limitedData.type ===
|
|
567
|
-
|
|
568
|
-
if (limitedData.filter === 1 && limitedData.exclude_product_ids?.includes(product.id)) {
|
|
520
|
+
if (limitedData.type === "product_all") {
|
|
521
|
+
if (limitedData.filter === 1 && ((_h = limitedData.exclude_product_ids) == null ? void 0 : _h.includes(product.id))) {
|
|
569
522
|
isLimitedProduct = false;
|
|
570
523
|
} else {
|
|
571
524
|
isLimitedProduct = true;
|
|
@@ -573,51 +526,33 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
573
526
|
} else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
|
|
574
527
|
isLimitedProduct = true;
|
|
575
528
|
}
|
|
576
|
-
|
|
577
|
-
// 套餐规则检查
|
|
578
529
|
const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
|
|
579
530
|
return isLimitedProduct && isBundleAvailable;
|
|
580
531
|
};
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
const selectedOrderLevelDiscounts = sortedDiscountList.filter(discount => {
|
|
584
|
-
return (0, _utils.isOrderLevelFixedAmountDiscount)(discount) && discount.isSelected !== false;
|
|
532
|
+
const selectedOrderLevelDiscounts = sortedDiscountList.filter((discount) => {
|
|
533
|
+
return (0, import_utils3.isOrderLevelFixedAmountDiscount)(discount) && discount.isSelected !== false;
|
|
585
534
|
});
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const applicableItemIds = new Set();
|
|
590
|
-
sortedFlattenedList.forEach(flatItem => {
|
|
535
|
+
selectedOrderLevelDiscounts.forEach((discount) => {
|
|
536
|
+
const applicableItemIds = /* @__PURE__ */ new Set();
|
|
537
|
+
sortedFlattenedList.forEach((flatItem) => {
|
|
591
538
|
if (checkItemApplicableForDiscount(flatItem, discount)) {
|
|
592
539
|
applicableItemIds.add(flatItem._id);
|
|
593
|
-
|
|
594
|
-
// 记录商品可以被哪些折扣卡使用
|
|
595
540
|
if (!itemApplicableDiscounts.has(flatItem._id)) {
|
|
596
|
-
itemApplicableDiscounts.set(flatItem._id, new Set());
|
|
541
|
+
itemApplicableDiscounts.set(flatItem._id, /* @__PURE__ */ new Set());
|
|
597
542
|
}
|
|
598
543
|
itemApplicableDiscounts.get(flatItem._id).add(discount.id);
|
|
599
544
|
}
|
|
600
545
|
});
|
|
601
546
|
orderLevelDiscountApplicableItems.set(discount.id, applicableItemIds);
|
|
602
547
|
});
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
// 如果专属折扣卡被勾选,它适用的商品会被占用,其他折扣卡均摊时应排除这些商品
|
|
606
|
-
// Map<flatItemId, discountId> - 记录被占用的商品及其对应的折扣卡
|
|
607
|
-
const occupiedItems = new Map();
|
|
608
|
-
|
|
609
|
-
// 按排序顺序遍历折扣卡,判断哪些是专属折扣卡
|
|
610
|
-
selectedOrderLevelDiscounts.forEach(discount => {
|
|
548
|
+
const occupiedItems = /* @__PURE__ */ new Map();
|
|
549
|
+
selectedOrderLevelDiscounts.forEach((discount) => {
|
|
611
550
|
const limitedData = discount.limited_relation_product_data;
|
|
612
|
-
|
|
613
|
-
// 判断是否是专属折扣卡(只能用于特定商品,而不是全品类)
|
|
614
|
-
const isExclusiveDiscount = limitedData.type !== 'product_all';
|
|
551
|
+
const isExclusiveDiscount = limitedData.type !== "product_all";
|
|
615
552
|
if (isExclusiveDiscount) {
|
|
616
|
-
// 专属折扣卡:它适用的所有商品都会被它占用
|
|
617
553
|
const applicableItems = orderLevelDiscountApplicableItems.get(discount.id);
|
|
618
554
|
if (applicableItems) {
|
|
619
|
-
applicableItems.forEach(itemId => {
|
|
620
|
-
// 如果商品还没被占用,则标记为被当前折扣卡占用
|
|
555
|
+
applicableItems.forEach((itemId) => {
|
|
621
556
|
if (!occupiedItems.has(itemId)) {
|
|
622
557
|
occupiedItems.set(itemId, discount.id);
|
|
623
558
|
}
|
|
@@ -625,26 +560,22 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
625
560
|
}
|
|
626
561
|
}
|
|
627
562
|
});
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
if (!(0, _utils.isOrderLevelFixedAmountDiscount)(discount)) {
|
|
563
|
+
sortedDiscountList.forEach((discount) => {
|
|
564
|
+
if (!(0, import_utils3.isOrderLevelFixedAmountDiscount)(discount)) {
|
|
631
565
|
return;
|
|
632
566
|
}
|
|
633
|
-
|
|
634
|
-
// 收集该折扣卡适用的商品(排除被其他专属折扣卡占用的商品)
|
|
635
567
|
const applicableProducts = [];
|
|
636
|
-
sortedFlattenedList.forEach(flatItem => {
|
|
637
|
-
|
|
568
|
+
sortedFlattenedList.forEach((flatItem) => {
|
|
569
|
+
var _a2, _b, _c;
|
|
638
570
|
const occupyingDiscountId = occupiedItems.get(flatItem._id);
|
|
639
|
-
if (occupyingDiscountId !==
|
|
640
|
-
// 该商品被其他专属折扣卡占用,跳过
|
|
571
|
+
if (occupyingDiscountId !== void 0 && occupyingDiscountId !== discount.id) {
|
|
641
572
|
return;
|
|
642
573
|
}
|
|
643
574
|
if (!checkItemApplicableForDiscount(flatItem, discount)) {
|
|
644
575
|
return;
|
|
645
576
|
}
|
|
646
577
|
let product;
|
|
647
|
-
if (flatItem.type ===
|
|
578
|
+
if (flatItem.type === "main") {
|
|
648
579
|
product = flatItem.product;
|
|
649
580
|
} else {
|
|
650
581
|
product = {
|
|
@@ -655,53 +586,33 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
655
586
|
num: flatItem.num
|
|
656
587
|
};
|
|
657
588
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
const quantity = flatItem.type === 'main' ? product.num || product.quantity || 1 : (product.num || product.quantity || 1) * (flatItem.parentProduct?.num || flatItem.parentProduct?.quantity || 1);
|
|
661
|
-
|
|
662
|
-
// 对于主商品:使用 price
|
|
663
|
-
// 对于子商品:优先使用 flatItem.original_price,否则使用 flatItem.price
|
|
664
|
-
const originalAmount = flatItem.type === 'main' ? Number(product.price ?? 0) : Number(flatItem.original_price ?? flatItem.price ?? 0);
|
|
665
|
-
|
|
666
|
-
// 传递 parentQuantity 用于差值处理时判断是否是真正的"数量为1"
|
|
589
|
+
const quantity = flatItem.type === "main" ? product.num || product.quantity || 1 : (product.num || product.quantity || 1) * (((_a2 = flatItem.parentProduct) == null ? void 0 : _a2.num) || ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1);
|
|
590
|
+
const originalAmount = flatItem.type === "main" ? Number(product.price ?? 0) : Number(flatItem.original_price ?? flatItem.price ?? 0);
|
|
667
591
|
const productData = {
|
|
668
592
|
productId: flatItem._id,
|
|
669
593
|
amount: originalAmount,
|
|
670
|
-
quantity
|
|
594
|
+
quantity
|
|
671
595
|
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
if (flatItem.type === 'bundle') {
|
|
675
|
-
productData.parentQuantity = flatItem.parentProduct?.quantity || 1;
|
|
596
|
+
if (flatItem.type === "bundle") {
|
|
597
|
+
productData.parentQuantity = ((_c = flatItem.parentProduct) == null ? void 0 : _c.quantity) || 1;
|
|
676
598
|
}
|
|
677
599
|
applicableProducts.push(productData);
|
|
678
600
|
});
|
|
679
|
-
|
|
680
|
-
// 计算分摊
|
|
681
601
|
if (applicableProducts.length > 0) {
|
|
682
|
-
const allocation = (0,
|
|
602
|
+
const allocation = (0, import_utils4.calculateOrderLevelDiscountAllocation)(discount, applicableProducts);
|
|
683
603
|
orderLevelDiscountAllocations.set(discount.id, allocation);
|
|
684
604
|
}
|
|
685
605
|
});
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
// 记录已应用优惠券的商品信息
|
|
691
|
-
const appliedDiscountProducts = new Map();
|
|
692
|
-
|
|
693
|
-
// 首先遍历所有商品和所有优惠券,确定每个优惠券的适用范围,包括isSelected为false的优惠券
|
|
694
|
-
// 🔥 使用扁平化后的列表,包含主商品和bundle子商品
|
|
695
|
-
sortedFlattenedList.forEach(flatItem => {
|
|
696
|
-
// 获取商品数据
|
|
606
|
+
const processedProductsMap = /* @__PURE__ */ new Map();
|
|
607
|
+
const appliedDiscountProducts = /* @__PURE__ */ new Map();
|
|
608
|
+
sortedFlattenedList.forEach((flatItem) => {
|
|
609
|
+
var _a2;
|
|
697
610
|
let product, originProduct;
|
|
698
|
-
if (flatItem.type ===
|
|
611
|
+
if (flatItem.type === "main") {
|
|
699
612
|
product = flatItem.product;
|
|
700
613
|
originProduct = flatItem.originProduct;
|
|
701
614
|
} else {
|
|
702
|
-
// bundle子商品:构造虚拟商品对象
|
|
703
615
|
product = {
|
|
704
|
-
startDate: flatItem?.parentProduct?.startDate,
|
|
705
616
|
_id: flatItem._id,
|
|
706
617
|
id: flatItem.id,
|
|
707
618
|
price: flatItem.price,
|
|
@@ -710,59 +621,58 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
710
621
|
total: flatItem.total,
|
|
711
622
|
origin_total: flatItem.origin_total,
|
|
712
623
|
booking_id: flatItem.booking_id,
|
|
713
|
-
discount_list: flatItem.discount_list || []
|
|
624
|
+
discount_list: flatItem.discount_list || [],
|
|
625
|
+
startDate: (_a2 = flatItem.parentProduct) == null ? void 0 : _a2.startDate
|
|
714
626
|
};
|
|
715
627
|
originProduct = flatItem.originProduct;
|
|
716
628
|
}
|
|
717
|
-
addModeDiscount.forEach(discount => {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
const _tempVar = flatItem
|
|
721
|
-
const isHolderMatch = this.checkHolderMatch(
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
629
|
+
addModeDiscount.forEach((discount) => {
|
|
630
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
631
|
+
const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
|
|
632
|
+
const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
|
|
633
|
+
const isHolderMatch = this.checkHolderMatch(
|
|
634
|
+
discount,
|
|
635
|
+
{
|
|
636
|
+
isNeedHolder: resolveIsFormSubject(_tempVar) && !(_tempVar == null ? void 0 : _tempVar.isNormalProduct),
|
|
637
|
+
holder_id: (_tempVar == null ? void 0 : _tempVar.holder_id) || product.holder_id
|
|
638
|
+
},
|
|
639
|
+
holders
|
|
640
|
+
);
|
|
725
641
|
let timeLimit = true;
|
|
726
|
-
timeLimit = !!(0,
|
|
727
|
-
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
642
|
+
timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
|
|
643
|
+
const isLimitedProduct = (limitedData.type === "product_all" && limitedData.filter !== 1 || limitedData.type === "product_all" && limitedData.filter === 1 && !limitedData.exclude_product_ids.includes(product.id) || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
|
|
644
|
+
const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_a3 = product == null ? void 0 : product.discount_list) == null ? void 0 : _a3.length) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.every(
|
|
645
|
+
(discount2) => discount2.id && [
|
|
646
|
+
"good_pass",
|
|
647
|
+
"discount_card",
|
|
648
|
+
"product_discount_card"
|
|
649
|
+
].includes(discount2.tag || discount2.type)
|
|
650
|
+
))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_d = (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) == null ? void 0 : _d.length) && ((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.every((discount2) => discount2.id)));
|
|
734
651
|
const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && discount.config?.isAvailable) {
|
|
738
|
-
// 记录此优惠券适用的商品
|
|
739
|
-
discountApplicability.get(discount.id)?.push(product.id);
|
|
740
|
-
|
|
741
|
-
// 记录可抵扣的商品详情
|
|
652
|
+
if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && ((_g = discount.config) == null ? void 0 : _g.isAvailable)) {
|
|
653
|
+
(_h = discountApplicability.get(discount.id)) == null ? void 0 : _h.push(product.id);
|
|
742
654
|
const applicableProducts = discountApplicableProducts.get(discount.id) || [];
|
|
743
655
|
const discountType = discount.tag || discount.type;
|
|
744
|
-
const isGoodPass = discountType ===
|
|
745
|
-
|
|
746
|
-
// 使用数量
|
|
747
|
-
const num = isGoodPass || flatItem?.type === 'main' ? 1 : product.num;
|
|
656
|
+
const isGoodPass = discountType === "good_pass";
|
|
657
|
+
const num = isGoodPass || (flatItem == null ? void 0 : flatItem.type) === "main" ? 1 : product.num;
|
|
748
658
|
const productData = {
|
|
749
659
|
amount: product.price * num,
|
|
750
660
|
type: discountType,
|
|
751
661
|
tag: discountType,
|
|
752
662
|
discount: {
|
|
753
|
-
discount_card_type: discount
|
|
663
|
+
discount_card_type: (_i = discount == null ? void 0 : discount.metadata) == null ? void 0 : _i.discount_card_type,
|
|
754
664
|
fixed_amount: product.price,
|
|
755
|
-
discount_calculation_mode: discount
|
|
665
|
+
discount_calculation_mode: (_j = discount == null ? void 0 : discount.metadata) == null ? void 0 : _j.discount_calculation_mode,
|
|
756
666
|
resource_id: discount.id,
|
|
757
667
|
title: discount.format_title,
|
|
758
668
|
original_amount: product.price || product.origin_total,
|
|
759
669
|
pre_value: discount.par_value,
|
|
760
|
-
product_id: originProduct.id,
|
|
670
|
+
product_id: originProduct.id || originProduct.product_id,
|
|
761
671
|
discount_product_id: discount.product_id
|
|
762
672
|
},
|
|
763
673
|
metadata: {
|
|
764
|
-
num
|
|
765
|
-
discount_rule_uncheck_flag: discount
|
|
674
|
+
num,
|
|
675
|
+
discount_rule_uncheck_flag: discount == null ? void 0 : discount.discount_rule_uncheck_flag
|
|
766
676
|
}
|
|
767
677
|
};
|
|
768
678
|
applicableProducts.push(productData);
|
|
@@ -770,132 +680,128 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
770
680
|
}
|
|
771
681
|
});
|
|
772
682
|
});
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
// 🔥 Option 折扣辅助函数
|
|
778
|
-
const applyDiscountToOptions = (options, discount) => {
|
|
779
|
-
if (!options?.length) return {
|
|
780
|
-
discountedOptions: options,
|
|
781
|
-
optionDiscountAmount: 0
|
|
782
|
-
};
|
|
683
|
+
const processedFlatItemsMap = /* @__PURE__ */ new Map();
|
|
684
|
+
const applyDiscountToOptions = (options2, discount) => {
|
|
685
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
686
|
+
return { discountedOptions: options2, optionDiscountAmount: 0 };
|
|
783
687
|
let optionDiscountAmount = 0;
|
|
784
|
-
const discountedOptions =
|
|
785
|
-
// 折前单价:优先 price,缺失再 add_price;已写回折后价时用 _original_price(或旧字段 _original_add_price)
|
|
688
|
+
const discountedOptions = options2.map((option) => {
|
|
786
689
|
const rawUnit = option._original_price ?? option._original_add_price ?? option.price ?? option.add_price;
|
|
787
690
|
const baseUnitNum = Number(rawUnit ?? 0);
|
|
788
|
-
if (baseUnitNum <= 0)
|
|
789
|
-
|
|
691
|
+
if (baseUnitNum <= 0)
|
|
692
|
+
return option;
|
|
693
|
+
const discountedPrice = (0, import_utils.getDiscountAmount)(discount, baseUnitNum, baseUnitNum);
|
|
790
694
|
const optQty = Number(option.num ?? option.quantity ?? 1);
|
|
791
|
-
optionDiscountAmount = new
|
|
792
|
-
const {
|
|
793
|
-
_original_add_price,
|
|
794
|
-
...rest
|
|
795
|
-
} = option;
|
|
695
|
+
optionDiscountAmount = new import_decimal.default(optionDiscountAmount).plus(new import_decimal.default(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
|
|
696
|
+
const { _original_add_price, ...rest } = option;
|
|
796
697
|
const tmpl = rest.price ?? rest.add_price;
|
|
797
|
-
const nextPrice = typeof tmpl ===
|
|
698
|
+
const nextPrice = typeof tmpl === "string" ? String(discountedPrice) : discountedPrice;
|
|
798
699
|
return {
|
|
799
700
|
...rest,
|
|
800
|
-
_original_price: option._original_price ?? (_original_add_price !==
|
|
701
|
+
_original_price: option._original_price ?? (_original_add_price !== void 0 ? _original_add_price : rawUnit),
|
|
801
702
|
price: nextPrice
|
|
802
703
|
};
|
|
803
704
|
});
|
|
804
|
-
return {
|
|
805
|
-
discountedOptions,
|
|
806
|
-
optionDiscountAmount
|
|
807
|
-
};
|
|
705
|
+
return { discountedOptions, optionDiscountAmount };
|
|
808
706
|
};
|
|
809
|
-
const restoreOptionPrices =
|
|
810
|
-
if (!
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
...rest
|
|
818
|
-
} = option;
|
|
819
|
-
return {
|
|
820
|
-
...rest,
|
|
821
|
-
price: orig
|
|
822
|
-
};
|
|
707
|
+
const restoreOptionPrices = (options2) => {
|
|
708
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
709
|
+
return options2;
|
|
710
|
+
return options2.map((option) => {
|
|
711
|
+
const orig = option._original_price !== void 0 ? option._original_price : option._original_add_price;
|
|
712
|
+
if (orig !== void 0) {
|
|
713
|
+
const { _original_price, _original_add_price, ...rest } = option;
|
|
714
|
+
return { ...rest, price: orig };
|
|
823
715
|
}
|
|
824
716
|
return option;
|
|
825
717
|
});
|
|
826
718
|
};
|
|
827
|
-
const getOptionTotal =
|
|
828
|
-
if (!
|
|
829
|
-
|
|
719
|
+
const getOptionTotal = (options2) => {
|
|
720
|
+
if (!(options2 == null ? void 0 : options2.length))
|
|
721
|
+
return 0;
|
|
722
|
+
return options2.reduce((sum, opt) => {
|
|
830
723
|
const unit = Number(opt.price ?? opt.add_price ?? 0);
|
|
831
724
|
const n = Number(opt.num ?? opt.quantity ?? 1);
|
|
832
|
-
return new
|
|
725
|
+
return new import_decimal.default(sum).plus(new import_decimal.default(unit).mul(n)).toNumber();
|
|
833
726
|
}, 0);
|
|
834
727
|
};
|
|
835
|
-
|
|
836
|
-
// 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
|
|
837
|
-
// 🔥 使用扁平化后的列表进行处理
|
|
838
728
|
sortedFlattenedList.forEach((flatItem, index) => {
|
|
839
|
-
|
|
729
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I;
|
|
840
730
|
let product, originProduct;
|
|
841
|
-
if (flatItem.type ===
|
|
731
|
+
if (flatItem.type === "main") {
|
|
842
732
|
product = flatItem.product;
|
|
843
733
|
originProduct = flatItem.originProduct;
|
|
844
734
|
} else {
|
|
845
|
-
// bundle子商品
|
|
846
735
|
product = {
|
|
847
|
-
startDate: flatItem?.parentProduct?.startDate,
|
|
848
736
|
_id: flatItem._id,
|
|
849
737
|
id: flatItem.id,
|
|
850
738
|
price: flatItem.price,
|
|
851
739
|
quantity: flatItem.quantity,
|
|
852
740
|
num: flatItem.num,
|
|
853
741
|
total: flatItem.total,
|
|
854
|
-
original_price: flatItem
|
|
855
|
-
origin_total: flatItem
|
|
742
|
+
original_price: (_a2 = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _a2.original_price,
|
|
743
|
+
origin_total: (_b = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _b.original_price,
|
|
856
744
|
booking_id: flatItem.booking_id,
|
|
857
|
-
discount_list: flatItem
|
|
745
|
+
discount_list: ((_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) || [],
|
|
746
|
+
startDate: (_d = flatItem.parentProduct) == null ? void 0 : _d.startDate
|
|
858
747
|
};
|
|
859
748
|
originProduct = flatItem.originProduct;
|
|
860
749
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
750
|
+
const isPersistedProduct = (product == null ? void 0 : product.booking_id) || (originProduct == null ? void 0 : originProduct.order_detail_id) || (originProduct == null ? void 0 : originProduct.orderDetailId) || (originProduct == null ? void 0 : originProduct.booking_id);
|
|
751
|
+
const hasExistingWalletDiscount = ((_e = product.discount_list) == null ? void 0 : _e.length) && ((_f = product == null ? void 0 : product.discount_list) == null ? void 0 : _f.every((discount) => {
|
|
752
|
+
var _a3;
|
|
753
|
+
const discountIdentity = discount.id ?? ((_a3 = discount.discount) == null ? void 0 : _a3.resource_id);
|
|
754
|
+
const discountType = discount.tag || discount.type;
|
|
755
|
+
return Boolean(
|
|
756
|
+
discountIdentity && ["good_pass", "discount_card", "product_discount_card"].includes(
|
|
757
|
+
discountType
|
|
758
|
+
)
|
|
759
|
+
);
|
|
760
|
+
}));
|
|
761
|
+
if (isPersistedProduct && hasExistingWalletDiscount) {
|
|
762
|
+
if (flatItem.type === "main") {
|
|
865
763
|
processedProductsMap.set(product._id, [originProduct]);
|
|
866
764
|
} else {
|
|
867
|
-
processedFlatItemsMap.set(flatItem._id, [
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
765
|
+
processedFlatItemsMap.set(flatItem._id, [
|
|
766
|
+
{
|
|
767
|
+
...flatItem,
|
|
768
|
+
processed: true
|
|
769
|
+
}
|
|
770
|
+
]);
|
|
871
771
|
}
|
|
872
772
|
return;
|
|
873
773
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
const applicableDiscounts = sortedDiscountList.filter(discount => {
|
|
877
|
-
// 🔥 检查策略可用性(针对 good_pass 和折扣卡)
|
|
774
|
+
const applicableDiscounts = sortedDiscountList.filter((discount) => {
|
|
775
|
+
var _a3, _b2, _c2, _d2;
|
|
878
776
|
const discountType = discount.tag || discount.type;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
777
|
+
const currentOriginUid = getOriginProductUid(originProduct);
|
|
778
|
+
const isReapplyEditModeDiscountForProduct = discount.isEditMode && reapplyBookingDiscountProductUids.size > 0 && currentOriginUid && reapplyBookingDiscountProductUids.has(String(currentOriginUid)) && discount.isSelected === true;
|
|
779
|
+
if (discount.isEditMode && reapplyBookingDiscountProductUids.size > 0) {
|
|
780
|
+
const uid = currentOriginUid;
|
|
781
|
+
if (!uid || !reapplyBookingDiscountProductUids.has(uid))
|
|
782
|
+
return false;
|
|
783
|
+
if (!discount.isSelected)
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
if (["good_pass", "discount_card", "product_discount_card"].includes(
|
|
787
|
+
discountType
|
|
788
|
+
) && !isReapplyEditModeDiscountForProduct) {
|
|
789
|
+
if (discount.config === void 0 || !((_a3 = discount == null ? void 0 : discount.config) == null ? void 0 : _a3.isAvailable)) {
|
|
882
790
|
return false;
|
|
883
791
|
}
|
|
884
792
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
// 如果优惠券已被使用,则跳过
|
|
793
|
+
if ((Number(product.price) <= 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.length) && (discount.tag || discount.type) === "good_pass")
|
|
794
|
+
return false;
|
|
795
|
+
if ((Number(product.price) <= 0 || !product.price) && !((_c2 = product.discount_list) == null ? void 0 : _c2.find((n) => {
|
|
796
|
+
var _a4;
|
|
797
|
+
return ((_a4 = n.discount) == null ? void 0 : _a4.resource_id) === discount.id;
|
|
798
|
+
})) && (discount.tag || discount.type) !== "good_pass")
|
|
799
|
+
return false;
|
|
893
800
|
const targetUsedDiscounts = usedDiscounts.get(discount.id);
|
|
894
|
-
if (targetUsedDiscounts && (discount.tag || discount.type) ===
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const maxUsagePerOrder = discount.config?.maxUsagePerOrder;
|
|
801
|
+
if (targetUsedDiscounts && (discount.tag || discount.type) === "good_pass")
|
|
802
|
+
return false;
|
|
803
|
+
if ((discount.tag || discount.type) === "good_pass") {
|
|
804
|
+
const maxUsagePerOrder = (_d2 = discount.config) == null ? void 0 : _d2.maxUsagePerOrder;
|
|
899
805
|
if (maxUsagePerOrder && maxUsagePerOrder > 0) {
|
|
900
806
|
const currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
|
|
901
807
|
if (currentUsedCount >= maxUsagePerOrder) {
|
|
@@ -903,47 +809,32 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
903
809
|
}
|
|
904
810
|
}
|
|
905
811
|
}
|
|
906
|
-
|
|
907
|
-
// 🔥 检查折扣卡的 applicableProductLimit 限制:折扣卡可使用的最大次数(跨商品全局)
|
|
908
|
-
const discountTypeForLimit = discount.tag || discount.type;
|
|
909
|
-
if (['discount_card', 'product_discount_card'].includes(discountTypeForLimit)) {
|
|
910
|
-
const applicableProductLimitConfig = discount.config?.applicableProductLimit || 0;
|
|
911
|
-
if (applicableProductLimitConfig > 0) {
|
|
912
|
-
const currentUsedLimitCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
|
|
913
|
-
if (currentUsedLimitCount >= applicableProductLimitConfig) {
|
|
914
|
-
return false;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
812
|
const limitedData = discount.limited_relation_product_data;
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
813
|
+
const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
|
|
814
|
+
const isHolderMatch = this.checkHolderMatch(
|
|
815
|
+
discount,
|
|
816
|
+
{
|
|
817
|
+
isNeedHolder: resolveIsFormSubject(_tempVar) && !(_tempVar == null ? void 0 : _tempVar.isNormalProduct),
|
|
818
|
+
holder_id: (_tempVar == null ? void 0 : _tempVar.holder_id) || product.holder_id
|
|
819
|
+
},
|
|
820
|
+
holders
|
|
821
|
+
);
|
|
822
|
+
if (!isHolderMatch)
|
|
823
|
+
return false;
|
|
928
824
|
let timeLimit = true;
|
|
929
|
-
timeLimit = !!(0,
|
|
825
|
+
timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], (product.startDate || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
|
|
930
826
|
if (!timeLimit) {
|
|
931
827
|
return false;
|
|
932
828
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
if (limitedData.type === 'product_all') {
|
|
936
|
-
if (!isProductIncludedByLimitedData(limitedData, product.id)) {
|
|
829
|
+
if (limitedData.type === "product_all") {
|
|
830
|
+
if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
|
|
937
831
|
return false;
|
|
938
832
|
}
|
|
939
|
-
|
|
940
|
-
// 检查 package_sub_item_usage_rules
|
|
941
833
|
if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
|
|
942
834
|
return false;
|
|
943
835
|
}
|
|
944
836
|
return true;
|
|
945
837
|
} else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
|
|
946
|
-
// 检查 package_sub_item_usage_rules
|
|
947
838
|
if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
|
|
948
839
|
return false;
|
|
949
840
|
}
|
|
@@ -951,369 +842,363 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
951
842
|
}
|
|
952
843
|
return false;
|
|
953
844
|
});
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
// 用于处理:先手动扫描了一张折扣卡,扫描完以后带入客户信息,但是之前那张折扣卡不是最优惠的情况
|
|
958
|
-
const selectedDiscountCard = applicableDiscounts.find(n => n.isScan && n.isSelected && (n.tag || n.type) !== 'good_pass');
|
|
845
|
+
const selectedDiscountCard = applicableDiscounts.find(
|
|
846
|
+
(n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
|
|
847
|
+
);
|
|
959
848
|
const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
|
|
960
|
-
|
|
961
|
-
// 如果是手动折扣,则不适用优惠券
|
|
962
849
|
let isManualDiscount = false;
|
|
963
|
-
if (flatItem.type ===
|
|
964
|
-
|
|
965
|
-
|
|
850
|
+
if (flatItem.type === "main") {
|
|
851
|
+
isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : ((_g = product.discount_list) == null ? void 0 : _g.some((item) => item.type === "product")) || product.total != product.origin_total && (product.bundle || []).every(
|
|
852
|
+
(item) => {
|
|
853
|
+
var _a3;
|
|
854
|
+
return !((_a3 = item.discount_list || []) == null ? void 0 : _a3.length);
|
|
855
|
+
}
|
|
856
|
+
) && (!((_h = product.discount_list) == null ? void 0 : _h.length) || ((_j = (_i = product == null ? void 0 : product.discount_list) == null ? void 0 : _i.every) == null ? void 0 : _j.call(
|
|
857
|
+
_i,
|
|
858
|
+
(item) => item.type === "product"
|
|
859
|
+
)));
|
|
966
860
|
if (product.inPromotion) {
|
|
967
861
|
isManualDiscount = false;
|
|
968
862
|
}
|
|
969
863
|
} else {
|
|
970
|
-
// bundle子商品:判断父主商品是否手动折扣
|
|
971
864
|
const parentProduct = flatItem.parentProduct;
|
|
972
865
|
if (parentProduct) {
|
|
973
|
-
isManualDiscount = typeof parentProduct.isManualDiscount ===
|
|
866
|
+
isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : ((_k = parentProduct.discount_list) == null ? void 0 : _k.some((item) => item.type === "product")) || parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(
|
|
867
|
+
(item) => {
|
|
868
|
+
var _a3;
|
|
869
|
+
return !((_a3 = item.discount_list || []) == null ? void 0 : _a3.length);
|
|
870
|
+
}
|
|
871
|
+
) && (!((_l = parentProduct.discount_list) == null ? void 0 : _l.length) || ((_n = (_m = parentProduct == null ? void 0 : parentProduct.discount_list) == null ? void 0 : _m.every) == null ? void 0 : _n.call(
|
|
872
|
+
_m,
|
|
873
|
+
(item) => item.type === "product"
|
|
874
|
+
)));
|
|
974
875
|
}
|
|
975
876
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
877
|
+
if (options == null ? void 0 : options.discountId) {
|
|
878
|
+
if (flatItem.type === "main" && ((_o = product.discount_list) == null ? void 0 : _o.some(
|
|
879
|
+
(item) => {
|
|
880
|
+
var _a3;
|
|
881
|
+
return ((_a3 = item.discount) == null ? void 0 : _a3.resource_id) === options.discountId;
|
|
882
|
+
}
|
|
883
|
+
))) {
|
|
981
884
|
isManualDiscount = false;
|
|
982
885
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
886
|
+
if (flatItem.type === "bundle") {
|
|
887
|
+
if (((_p = product.discount_list) == null ? void 0 : _p.some(
|
|
888
|
+
(item) => {
|
|
889
|
+
var _a3;
|
|
890
|
+
return ((_a3 = item.discount) == null ? void 0 : _a3.resource_id) === options.discountId;
|
|
891
|
+
}
|
|
892
|
+
)) || ((_r = (_q = flatItem.parentProduct) == null ? void 0 : _q.discount_list) == null ? void 0 : _r.some(
|
|
893
|
+
(item) => {
|
|
894
|
+
var _a3;
|
|
895
|
+
return ((_a3 = item.discount) == null ? void 0 : _a3.resource_id) === options.discountId;
|
|
896
|
+
}
|
|
897
|
+
))) {
|
|
986
898
|
isManualDiscount = false;
|
|
987
899
|
}
|
|
988
900
|
}
|
|
989
901
|
}
|
|
990
|
-
if (options
|
|
991
|
-
|
|
992
|
-
|
|
902
|
+
if (options == null ? void 0 : options.selectedList) {
|
|
903
|
+
if (flatItem.type === "main" && ((_s = product.discount_list) == null ? void 0 : _s.some(
|
|
904
|
+
(item) => {
|
|
905
|
+
var _a3;
|
|
906
|
+
return (_a3 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a3.some(
|
|
907
|
+
(n) => {
|
|
908
|
+
var _a4;
|
|
909
|
+
return n.discountId === ((_a4 = item.discount) == null ? void 0 : _a4.resource_id);
|
|
910
|
+
}
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
))) {
|
|
993
914
|
isManualDiscount = false;
|
|
994
915
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
916
|
+
if (flatItem.type === "bundle") {
|
|
917
|
+
if (((_t = product.discount_list) == null ? void 0 : _t.some(
|
|
918
|
+
(item) => {
|
|
919
|
+
var _a3;
|
|
920
|
+
return (_a3 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a3.some(
|
|
921
|
+
(n) => {
|
|
922
|
+
var _a4;
|
|
923
|
+
return n.discountId === ((_a4 = item.discount) == null ? void 0 : _a4.resource_id);
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
)) || ((_v = (_u = flatItem.parentProduct) == null ? void 0 : _u.discount_list) == null ? void 0 : _v.some(
|
|
928
|
+
(item) => {
|
|
929
|
+
var _a3;
|
|
930
|
+
return (_a3 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a3.some(
|
|
931
|
+
(n) => {
|
|
932
|
+
var _a4;
|
|
933
|
+
return n.discountId === ((_a4 = item.discount) == null ? void 0 : _a4.resource_id);
|
|
934
|
+
}
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
))) {
|
|
998
938
|
isManualDiscount = false;
|
|
999
939
|
}
|
|
1000
940
|
}
|
|
1001
941
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
if (applicableDiscounts.length === 0 || isManualDiscount || (0, _lodashEs.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
1005
|
-
if (flatItem.type === 'main') {
|
|
1006
|
-
// 主商品:保持原有逻辑,还原 option 价格
|
|
942
|
+
if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
943
|
+
if (flatItem.type === "main") {
|
|
1007
944
|
const restoredOptions = restoreOptionPrices(product.options);
|
|
1008
945
|
if (product.isClient) {
|
|
1009
|
-
processedProductsMap.set(product._id, [
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
946
|
+
processedProductsMap.set(product._id, [
|
|
947
|
+
this.hooks.setProduct(originProduct, {
|
|
948
|
+
...isManualDiscount ? {} : {
|
|
949
|
+
origin_total: (0, import_utils2.getProductOriginTotalPrice)({
|
|
950
|
+
product: {
|
|
951
|
+
original_price: product.original_price
|
|
952
|
+
},
|
|
953
|
+
bundle: product.bundle,
|
|
954
|
+
options: restoredOptions
|
|
955
|
+
}),
|
|
956
|
+
variant: originProduct._productInit.variant,
|
|
957
|
+
original_price: originProduct._productInit.original_price,
|
|
958
|
+
total: (0, import_utils2.getProductTotalPrice)({
|
|
959
|
+
product: {
|
|
960
|
+
price: product.price
|
|
961
|
+
},
|
|
962
|
+
bundle: product.bundle,
|
|
963
|
+
options: restoredOptions
|
|
964
|
+
}),
|
|
965
|
+
price: product.price,
|
|
1016
966
|
options: restoredOptions
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
product: {
|
|
1022
|
-
price: product.price
|
|
1023
|
-
},
|
|
1024
|
-
bundle: product.bundle,
|
|
1025
|
-
options: restoredOptions
|
|
1026
|
-
}),
|
|
1027
|
-
price: product.price,
|
|
1028
|
-
options: restoredOptions
|
|
1029
|
-
}),
|
|
1030
|
-
discount_list: this.filterDiscountListByType(product.discount_list, 'promotion')
|
|
1031
|
-
})]);
|
|
967
|
+
},
|
|
968
|
+
discount_list: isManualDiscount ? this.resolveDiscountListForManualOverride(product.discount_list) : this.filterDiscountListByType(product.discount_list, "promotion")
|
|
969
|
+
})
|
|
970
|
+
]);
|
|
1032
971
|
} else {
|
|
1033
|
-
let total = product.inPromotion ? product
|
|
1034
|
-
let main_product_selling_price = product.price
|
|
1035
|
-
if ((product.discount_list || []).some(item => item.type ===
|
|
972
|
+
let total = product.inPromotion ? ((_w = product == null ? void 0 : product._promotion) == null ? void 0 : _w.finalPrice) ?? product.origin_total ?? product.total : product.origin_total ?? product.total;
|
|
973
|
+
let main_product_selling_price = product.price;
|
|
974
|
+
if ((product.discount_list || []).some((item) => item.type === "promotion") || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
1036
975
|
total = product.total ?? product.origin_total;
|
|
1037
976
|
main_product_selling_price = product.main_product_selling_price ?? main_product_selling_price;
|
|
1038
977
|
}
|
|
1039
|
-
processedProductsMap.set(product._id, [
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
978
|
+
processedProductsMap.set(product._id, [
|
|
979
|
+
this.hooks.setProduct(originProduct, {
|
|
980
|
+
...isManualDiscount ? {
|
|
981
|
+
price: product.price
|
|
982
|
+
} : {
|
|
983
|
+
_id: product._id.split("___")[0] + "___" + index,
|
|
984
|
+
total,
|
|
985
|
+
price: product.price,
|
|
986
|
+
main_product_selling_price,
|
|
987
|
+
options: restoredOptions
|
|
988
|
+
},
|
|
989
|
+
discount_list: isManualDiscount ? this.resolveDiscountListForManualOverride(product.discount_list) : this.filterDiscountListByType(product.discount_list, "promotion")
|
|
990
|
+
})
|
|
991
|
+
]);
|
|
1052
992
|
}
|
|
1053
993
|
} else {
|
|
1054
|
-
// bundle子商品:保存到扁平化Map
|
|
1055
994
|
processedFlatItemsMap.set(flatItem._id, [{
|
|
1056
995
|
...flatItem,
|
|
1057
|
-
discount_list: this.filterDiscountListByType(flatItem.bundleItem
|
|
996
|
+
discount_list: isManualDiscount ? this.resolveDiscountListForManualOverride(((_x = flatItem.bundleItem) == null ? void 0 : _x.discount_list) || []) : this.filterDiscountListByType(((_y = flatItem.bundleItem) == null ? void 0 : _y.discount_list) || [], "promotion"),
|
|
1058
997
|
price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
|
|
1059
998
|
processed: true
|
|
1060
999
|
}]);
|
|
1061
1000
|
}
|
|
1062
1001
|
return;
|
|
1063
1002
|
}
|
|
1064
|
-
|
|
1003
|
+
const shouldReapplyBookingDiscountForProduct = shouldReapplyBookingDiscount(originProduct, selectedDiscount);
|
|
1004
|
+
if (applicableDiscounts.length && product.booking_id && typeof selectedDiscount.isManualSelect === "undefined" && !(options == null ? void 0 : options.scan) && !isEditModeAddNewProduct && !shouldReapplyBookingDiscountForProduct) {
|
|
1065
1005
|
return;
|
|
1066
1006
|
}
|
|
1067
|
-
|
|
1068
|
-
// 是否需要拆分(商品券需要拆分,折扣卡在 applicableProductLimit > 0 时也需要拆分)
|
|
1069
|
-
const discountType = selectedDiscount.tag || selectedDiscount.type;
|
|
1070
|
-
const isGoodPass = discountType === 'good_pass';
|
|
1071
|
-
const isDiscountCard = ['discount_card', 'product_discount_card'].includes(discountType);
|
|
1072
|
-
const applicableProductLimit = selectedDiscount.config?.applicableProductLimit || 0;
|
|
1073
|
-
|
|
1074
|
-
// 商品券始终需要拆分,折扣卡在 applicableProductLimit > 0 时需要拆分
|
|
1075
|
-
const isNeedSplit = isGoodPass || isDiscountCard && applicableProductLimit > 0;
|
|
1076
|
-
|
|
1077
|
-
// 需要拆分出来的数量
|
|
1007
|
+
const isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === "good_pass";
|
|
1078
1008
|
const totalQuantity = product.quantity || product.num || 1;
|
|
1079
|
-
const availableGoodPassCount = applicableDiscounts.filter(
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
let maxUsageLimit;
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
}
|
|
1089
|
-
} else if (isDiscountCard && applicableProductLimit > 0) {
|
|
1090
|
-
// 折扣卡:使用 applicableProductLimit 限制(一个商品使用一次折扣卡算1次)
|
|
1091
|
-
// 需要减去已使用次数(跨商品全局计数)
|
|
1092
|
-
const usedLimitCount = usedDiscountCardLimitCounts.get(selectedDiscount.id) || 0;
|
|
1093
|
-
maxUsageLimit = Math.max(0, applicableProductLimit - usedLimitCount);
|
|
1094
|
-
} else {
|
|
1095
|
-
// 其他情况不拆分
|
|
1096
|
-
maxUsageLimit = 1;
|
|
1009
|
+
const availableGoodPassCount = applicableDiscounts.filter(
|
|
1010
|
+
(item) => (item.tag || item.type) === "good_pass"
|
|
1011
|
+
).length;
|
|
1012
|
+
let maxUsageLimit = availableGoodPassCount;
|
|
1013
|
+
if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
|
|
1014
|
+
maxUsageLimit = Math.min(
|
|
1015
|
+
availableGoodPassCount,
|
|
1016
|
+
selectedDiscount.config.maxUsagePerOrder
|
|
1017
|
+
);
|
|
1097
1018
|
}
|
|
1098
1019
|
const splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
|
|
1099
1020
|
const arr = [];
|
|
1100
|
-
|
|
1101
|
-
// 🔥 主商品和bundle子商品分别处理
|
|
1102
|
-
if (flatItem.type === 'main') {
|
|
1103
|
-
// 主商品:保持原有逻辑
|
|
1021
|
+
if (flatItem.type === "main") {
|
|
1104
1022
|
if (splitCount < totalQuantity && isNeedSplit) {
|
|
1105
1023
|
let total = product.origin_total ?? product.total;
|
|
1106
|
-
if ((product.discount_list || []).some(item => item.type ===
|
|
1024
|
+
if ((product.discount_list || []).some((item) => item.type === "promotion")) {
|
|
1107
1025
|
total = product.total ?? product.origin_total;
|
|
1108
1026
|
}
|
|
1109
|
-
arr.push(
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1027
|
+
arr.push(
|
|
1028
|
+
this.hooks.setProduct(originProduct, {
|
|
1029
|
+
discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
|
|
1030
|
+
quantity: totalQuantity - splitCount,
|
|
1031
|
+
_id: product._id.split("___")[0],
|
|
1032
|
+
total
|
|
1033
|
+
})
|
|
1034
|
+
);
|
|
1115
1035
|
}
|
|
1116
1036
|
for (let i = 0; i < splitCount; i++) {
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
// 🔥 更新 product_id 使用计数
|
|
1123
|
-
if ((currentSelectedDiscount.tag || currentSelectedDiscount.type) === 'good_pass') {
|
|
1124
|
-
const currentCount = usedProductIdCounts.get(currentSelectedDiscount.product_id) || 0;
|
|
1125
|
-
usedProductIdCounts.set(currentSelectedDiscount.product_id, currentCount + 1);
|
|
1126
|
-
}
|
|
1127
|
-
// 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
|
|
1128
|
-
const currentDiscountTypeForCount = currentSelectedDiscount.tag || currentSelectedDiscount.type;
|
|
1129
|
-
if (['discount_card', 'product_discount_card'].includes(currentDiscountTypeForCount)) {
|
|
1130
|
-
const currentLimitCount = usedDiscountCardLimitCounts.get(currentSelectedDiscount.id) || 0;
|
|
1131
|
-
usedDiscountCardLimitCounts.set(currentSelectedDiscount.id, currentLimitCount + 1);
|
|
1037
|
+
const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
|
|
1038
|
+
usedDiscounts.set(selectedDiscount2.id, true);
|
|
1039
|
+
if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
|
|
1040
|
+
const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
|
|
1041
|
+
usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
|
|
1132
1042
|
}
|
|
1133
|
-
|
|
1134
|
-
// 记录实际应用了优惠券的商品信息
|
|
1135
|
-
const appliedProducts = appliedDiscountProducts.get(currentSelectedDiscount.id) || [];
|
|
1136
|
-
|
|
1137
|
-
// 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
|
|
1043
|
+
const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
|
|
1138
1044
|
let productOriginTotal = product.origin_total || product.total || 0;
|
|
1139
|
-
|
|
1140
|
-
if (this.filterDiscountListByType(product.discount_list, 'promotion').length && product.origin_total) {
|
|
1045
|
+
if (this.filterDiscountListByType(product.discount_list, "promotion").length && product.origin_total) {
|
|
1141
1046
|
productOriginTotal = product.origin_total;
|
|
1142
1047
|
}
|
|
1143
|
-
|
|
1144
|
-
if (Number(originProduct?._productInit?.original_price || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
|
|
1048
|
+
if (Number(((_z = originProduct == null ? void 0 : originProduct._productInit) == null ? void 0 : _z.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
|
|
1145
1049
|
productOriginTotal = product.total;
|
|
1146
1050
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
const
|
|
1151
|
-
const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
|
|
1152
|
-
const productAllocation = orderLevelAllocation?.get(flatItem._id);
|
|
1153
|
-
const isDeductOptionPrice = !!selectedDiscount.config?.deductOptionPrice;
|
|
1154
|
-
|
|
1155
|
-
// 主商品折后价(不含 option);勿与 option 合计混在同一变量,否则 main_product_selling_price 错误
|
|
1051
|
+
const isOrderLevel = (0, import_utils3.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
|
|
1052
|
+
const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
|
|
1053
|
+
const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
|
|
1054
|
+
const isDeductOptionPrice = !!((_A = selectedDiscount2.config) == null ? void 0 : _A.deductOptionPrice);
|
|
1156
1055
|
let mainProductSellingPrice;
|
|
1157
1056
|
let amount;
|
|
1158
1057
|
let productDiscountDifference;
|
|
1159
1058
|
let discountedOptions = product.options;
|
|
1160
1059
|
let optionDiscountAmount = 0;
|
|
1060
|
+
let reapplyDiscountPercent;
|
|
1161
1061
|
if (isOrderLevel && productAllocation) {
|
|
1162
|
-
// order_level:使用预计算的分摊金额
|
|
1163
1062
|
amount = productAllocation.discountAmount;
|
|
1164
1063
|
productDiscountDifference = productAllocation.difference;
|
|
1165
|
-
mainProductSellingPrice = Math.max(new
|
|
1064
|
+
mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
|
|
1065
|
+
} else if (resolveReapplyEditModeDiscountPercent(originProduct, selectedDiscount2) !== void 0) {
|
|
1066
|
+
const percent = resolveReapplyEditModeDiscountPercent(originProduct, selectedDiscount2);
|
|
1067
|
+
reapplyDiscountPercent = new import_decimal.default(percent).toFixed(2);
|
|
1068
|
+
mainProductSellingPrice = new import_decimal.default(product.price || 0).mul(new import_decimal.default(100).minus(percent)).div(100).toDecimalPlaces(2).toNumber();
|
|
1069
|
+
amount = new import_decimal.default(product.price).minus(mainProductSellingPrice).toNumber();
|
|
1166
1070
|
} else {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1071
|
+
mainProductSellingPrice = (0, import_utils.getDiscountAmount)(
|
|
1072
|
+
selectedDiscount2,
|
|
1073
|
+
product.price,
|
|
1074
|
+
product.price
|
|
1075
|
+
);
|
|
1076
|
+
amount = new import_decimal.default(product.price).minus(new import_decimal.default(mainProductSellingPrice)).toNumber();
|
|
1170
1077
|
}
|
|
1171
|
-
if (isDeductOptionPrice && product.options
|
|
1172
|
-
const optionResult = applyDiscountToOptions(
|
|
1078
|
+
if (isDeductOptionPrice && ((_B = product.options) == null ? void 0 : _B.length)) {
|
|
1079
|
+
const optionResult = applyDiscountToOptions(
|
|
1080
|
+
product.options,
|
|
1081
|
+
selectedDiscount2
|
|
1082
|
+
);
|
|
1173
1083
|
discountedOptions = optionResult.discountedOptions;
|
|
1174
1084
|
optionDiscountAmount = optionResult.optionDiscountAmount;
|
|
1175
1085
|
}
|
|
1176
|
-
|
|
1177
|
-
// total = 主商品折后 + option 行合计;开启 option 抵扣时必须用 discountedOptions,不能用未折扣的 product.options 再算一遍
|
|
1178
|
-
const optionsForLineTotal = isDeductOptionPrice && product.options?.length ? discountedOptions : product.options;
|
|
1086
|
+
const optionsForLineTotal = isDeductOptionPrice && ((_C = product.options) == null ? void 0 : _C.length) ? discountedOptions : product.options;
|
|
1179
1087
|
const optionsLineTotal = getOptionTotal(optionsForLineTotal || []);
|
|
1180
|
-
const total = new
|
|
1181
|
-
|
|
1182
|
-
// discount_list.amount / fixed_amount:行级总优惠 = 主商品优惠 + option 优惠(与 total 变化一致)
|
|
1088
|
+
const total = new import_decimal.default(mainProductSellingPrice).plus(optionsLineTotal).toNumber();
|
|
1183
1089
|
const mainProductDiscountAmount = amount;
|
|
1184
|
-
const lineDiscountAmount = new
|
|
1185
|
-
const
|
|
1186
|
-
const
|
|
1187
|
-
const currentIsGoodPass = currentDiscountType === 'good_pass';
|
|
1090
|
+
const lineDiscountAmount = new import_decimal.default(mainProductDiscountAmount).plus(optionDiscountAmount).toNumber();
|
|
1091
|
+
const discountType = selectedDiscount2.tag || selectedDiscount2.type;
|
|
1092
|
+
const isGoodPass = discountType === "good_pass";
|
|
1188
1093
|
const discountDetail = {
|
|
1189
1094
|
amount: lineDiscountAmount,
|
|
1190
|
-
type:
|
|
1095
|
+
type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : discountType,
|
|
1191
1096
|
discount: {
|
|
1192
|
-
discount_card_type:
|
|
1097
|
+
discount_card_type: (_D = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _D.discount_card_type,
|
|
1193
1098
|
fixed_amount: lineDiscountAmount,
|
|
1194
|
-
discount_calculation_mode:
|
|
1195
|
-
resource_id:
|
|
1196
|
-
title:
|
|
1099
|
+
discount_calculation_mode: (_E = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _E.discount_calculation_mode,
|
|
1100
|
+
resource_id: selectedDiscount2.id,
|
|
1101
|
+
title: selectedDiscount2.format_title,
|
|
1197
1102
|
original_amount: product.price,
|
|
1198
|
-
product_id: originProduct.id,
|
|
1199
|
-
percent:
|
|
1200
|
-
discount_product_id:
|
|
1103
|
+
product_id: originProduct.id || originProduct.product_id,
|
|
1104
|
+
percent: reapplyDiscountPercent ?? selectedDiscount2.par_value,
|
|
1105
|
+
discount_product_id: selectedDiscount2.product_id
|
|
1201
1106
|
},
|
|
1202
|
-
// 前端使用的num
|
|
1203
|
-
_num:
|
|
1204
|
-
config:
|
|
1107
|
+
// 前端使用的num数量,为了计算优惠金额
|
|
1108
|
+
_num: isGoodPass ? 1 : product.num,
|
|
1109
|
+
config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config,
|
|
1205
1110
|
metadata: {
|
|
1206
1111
|
num: 1,
|
|
1207
|
-
discount_rule_uncheck_flag:
|
|
1112
|
+
discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
|
|
1208
1113
|
// 🔥 order_level 分摊差值
|
|
1209
|
-
...
|
|
1210
|
-
product_discount_difference: productDiscountDifference
|
|
1211
|
-
}),
|
|
1114
|
+
...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference },
|
|
1212
1115
|
/** 仅主商品上的优惠金额(不含 option) */
|
|
1213
1116
|
mainProductDiscountAmount,
|
|
1214
1117
|
optionDiscountAmount
|
|
1215
1118
|
}
|
|
1216
1119
|
};
|
|
1217
1120
|
appliedProducts.push(discountDetail);
|
|
1218
|
-
appliedDiscountProducts.set(
|
|
1219
|
-
|
|
1220
|
-
// 记录应用了优惠券的商品
|
|
1221
|
-
// 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
|
|
1121
|
+
appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
|
|
1222
1122
|
if (product.isClient) {
|
|
1223
|
-
arr.push(
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1123
|
+
arr.push(
|
|
1124
|
+
this.hooks.setProduct(originProduct, {
|
|
1125
|
+
discount_list: [discountDetail],
|
|
1126
|
+
// good_pass:主商品价以折后价为准;勿用 product.price - amount(amount 含 option 优惠时会算错)
|
|
1127
|
+
price: isGoodPass ? mainProductSellingPrice : product.price,
|
|
1128
|
+
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1129
|
+
origin_total: (0, import_utils2.getProductOriginTotalPrice)({
|
|
1130
|
+
product: {
|
|
1131
|
+
original_price: product.original_price
|
|
1132
|
+
},
|
|
1133
|
+
bundle: product.bundle,
|
|
1134
|
+
options: restoreOptionPrices(product.options)
|
|
1135
|
+
}),
|
|
1136
|
+
variant: originProduct._productInit.variant,
|
|
1137
|
+
original_price: new import_decimal.default(product.price || 0).toNumber(),
|
|
1138
|
+
total,
|
|
1139
|
+
options: discountedOptions
|
|
1140
|
+
})
|
|
1141
|
+
);
|
|
1240
1142
|
} else {
|
|
1241
|
-
arr.push(
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1143
|
+
arr.push(
|
|
1144
|
+
this.hooks.setProduct(originProduct, {
|
|
1145
|
+
discount_list: this.filterDiscountListByType(product.discount_list, "promotion").concat([discountDetail]),
|
|
1146
|
+
_id: product._id.split("___")[0] + "___" + selectedDiscount2.id + index,
|
|
1147
|
+
price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
|
|
1148
|
+
quantity: isNeedSplit ? 1 : product.quantity,
|
|
1149
|
+
total,
|
|
1150
|
+
origin_total: productOriginTotal,
|
|
1151
|
+
main_product_selling_price: mainProductSellingPrice,
|
|
1152
|
+
options: discountedOptions
|
|
1153
|
+
})
|
|
1154
|
+
);
|
|
1251
1155
|
}
|
|
1252
1156
|
}
|
|
1253
1157
|
processedProductsMap.set(product._id, arr);
|
|
1254
1158
|
} else {
|
|
1255
|
-
// 🔥 bundle子商品:支持拆分(商品券和折扣卡在 applicableProductLimit > 0 时都需要拆分)
|
|
1256
1159
|
const processedItems = [];
|
|
1257
1160
|
if (isNeedSplit) {
|
|
1258
|
-
// 需要拆分数量(商品券或折扣卡有 applicableProductLimit 限制)
|
|
1259
1161
|
const discountNum = splitCount;
|
|
1260
1162
|
const normalNum = totalQuantity - discountNum;
|
|
1261
|
-
|
|
1262
|
-
// 生成有折扣的商品(每个拆分商品 num: 1)
|
|
1263
1163
|
for (let i = 0; i < discountNum; i++) {
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
if ((currentBundleDiscount.tag || currentBundleDiscount.type) === 'good_pass') {
|
|
1270
|
-
const currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
|
|
1271
|
-
usedProductIdCounts.set(currentBundleDiscount.product_id, currentCount + 1);
|
|
1272
|
-
}
|
|
1273
|
-
// 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
|
|
1274
|
-
const bundleDiscountTypeForCount = currentBundleDiscount.tag || currentBundleDiscount.type;
|
|
1275
|
-
if (['discount_card', 'product_discount_card'].includes(bundleDiscountTypeForCount)) {
|
|
1276
|
-
const currentBundleLimitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
|
|
1277
|
-
usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentBundleLimitCount + 1);
|
|
1164
|
+
const selectedDiscount2 = applicableDiscounts[i];
|
|
1165
|
+
usedDiscounts.set(selectedDiscount2.id, true);
|
|
1166
|
+
if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
|
|
1167
|
+
const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
|
|
1168
|
+
usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
|
|
1278
1169
|
}
|
|
1279
|
-
|
|
1280
|
-
// 🔥 生成唯一的 _id
|
|
1281
1170
|
const uniqueId = `${flatItem._id}_split_${i}`;
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1171
|
+
const discountedPrice = (0, import_utils.getDiscountAmount)(
|
|
1172
|
+
selectedDiscount2,
|
|
1173
|
+
product.origin_total,
|
|
1174
|
+
product.origin_total
|
|
1175
|
+
);
|
|
1176
|
+
const bundleDiscountAmount = new import_decimal.default(product.origin_total || 0).minus(discountedPrice).toNumber();
|
|
1177
|
+
debugger;
|
|
1289
1178
|
const discountDetail = {
|
|
1290
1179
|
amount: bundleDiscountAmount,
|
|
1291
|
-
type:
|
|
1180
|
+
type: "good_pass",
|
|
1292
1181
|
discount: {
|
|
1293
|
-
|
|
1294
|
-
discount_calculation_mode:
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
title: currentBundleDiscount.format_title,
|
|
1182
|
+
fixed_amount: product.origin_total,
|
|
1183
|
+
discount_calculation_mode: (_F = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _F.discount_calculation_mode,
|
|
1184
|
+
resource_id: selectedDiscount2.id,
|
|
1185
|
+
title: selectedDiscount2.format_title,
|
|
1298
1186
|
original_amount: product.origin_total,
|
|
1299
|
-
product_id: product.id,
|
|
1300
|
-
|
|
1301
|
-
discount_product_id: currentBundleDiscount.product_id
|
|
1187
|
+
product_id: product.id || product.product_id,
|
|
1188
|
+
discount_product_id: selectedDiscount2.product_id
|
|
1302
1189
|
},
|
|
1303
1190
|
metadata: {
|
|
1304
1191
|
// 🔥 使用拆分后的唯一 _id
|
|
1305
1192
|
custom_product_bundle_map_id: uniqueId,
|
|
1306
|
-
discount_rule_uncheck_flag:
|
|
1193
|
+
discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
|
|
1307
1194
|
num: 1
|
|
1308
1195
|
},
|
|
1309
1196
|
_num: 1,
|
|
1310
|
-
config:
|
|
1197
|
+
config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config
|
|
1311
1198
|
};
|
|
1312
|
-
|
|
1313
|
-
// 记录实际应用的折扣
|
|
1314
|
-
const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
|
|
1199
|
+
const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
|
|
1315
1200
|
appliedProducts.push(discountDetail);
|
|
1316
|
-
appliedDiscountProducts.set(
|
|
1201
|
+
appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
|
|
1317
1202
|
processedItems.push({
|
|
1318
1203
|
...flatItem,
|
|
1319
1204
|
// 🔥 使用唯一的 _id
|
|
@@ -1325,332 +1210,100 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1325
1210
|
total: discountedPrice,
|
|
1326
1211
|
discount_list: [discountDetail],
|
|
1327
1212
|
processed: true,
|
|
1328
|
-
_discountId:
|
|
1213
|
+
_discountId: selectedDiscount2.id
|
|
1329
1214
|
});
|
|
1330
1215
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
if (['good_pass', 'discount_card', 'product_discount_card'].includes(nextDiscountType)) {
|
|
1341
|
-
if (nextDiscount.config === undefined || !nextDiscount?.config?.isAvailable) {
|
|
1342
|
-
return false;
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
// 折扣卡时总价为0时不可用
|
|
1346
|
-
if ((Number(product.total) <= 0 || !product.total) && !product.discount_list?.find(n => n.discount?.resource_id === nextDiscount.id) && nextDiscountType !== 'good_pass') return false;
|
|
1347
|
-
|
|
1348
|
-
// 商品券已被使用则跳过
|
|
1349
|
-
if (usedDiscounts.get(nextDiscount.id) && nextDiscountType === 'good_pass') return false;
|
|
1350
|
-
|
|
1351
|
-
// 检查 maxUsagePerOrder 限制
|
|
1352
|
-
if (nextDiscountType === 'good_pass') {
|
|
1353
|
-
const maxUsagePerOrder = nextDiscount.config?.maxUsagePerOrder;
|
|
1354
|
-
if (maxUsagePerOrder && maxUsagePerOrder > 0) {
|
|
1355
|
-
const currentUsedCount = usedProductIdCounts.get(nextDiscount.product_id) || 0;
|
|
1356
|
-
if (currentUsedCount >= maxUsagePerOrder) {
|
|
1357
|
-
return false;
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
// 检查折扣卡的 applicableProductLimit 限制
|
|
1363
|
-
if (['discount_card', 'product_discount_card'].includes(nextDiscountType)) {
|
|
1364
|
-
const limitConfig = nextDiscount.config?.applicableProductLimit || 0;
|
|
1365
|
-
if (limitConfig > 0) {
|
|
1366
|
-
const currentUsedLimitCount = usedDiscountCardLimitCounts.get(nextDiscount.id) || 0;
|
|
1367
|
-
if (currentUsedLimitCount >= limitConfig) {
|
|
1368
|
-
return false;
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
const limitedData = nextDiscount.limited_relation_product_data;
|
|
1373
|
-
if (limitedData.type === 'product_all') {
|
|
1374
|
-
if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
|
|
1375
|
-
return false;
|
|
1376
|
-
}
|
|
1377
|
-
if (!this.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
|
|
1378
|
-
return false;
|
|
1379
|
-
}
|
|
1380
|
-
return true;
|
|
1381
|
-
} else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
|
|
1382
|
-
if (!this.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
|
|
1383
|
-
return false;
|
|
1384
|
-
}
|
|
1385
|
-
return true;
|
|
1386
|
-
}
|
|
1387
|
-
return false;
|
|
1216
|
+
if (normalNum > 0) {
|
|
1217
|
+
processedItems.push({
|
|
1218
|
+
...flatItem,
|
|
1219
|
+
// 🔥 为剩余商品生成唯一的 _id
|
|
1220
|
+
_id: `${flatItem._id}_split_rest`,
|
|
1221
|
+
num: normalNum,
|
|
1222
|
+
quantity: normalNum,
|
|
1223
|
+
discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion"),
|
|
1224
|
+
processed: true
|
|
1388
1225
|
});
|
|
1389
|
-
|
|
1390
|
-
// 没有更多可用折扣,剩余商品无折扣存储
|
|
1391
|
-
if (nextApplicableDiscounts.length === 0) {
|
|
1392
|
-
processedItems.push({
|
|
1393
|
-
...flatItem,
|
|
1394
|
-
_id: `${flatItem._id}_split_rest`,
|
|
1395
|
-
num: remainingNum,
|
|
1396
|
-
quantity: remainingNum,
|
|
1397
|
-
discount_list: [],
|
|
1398
|
-
processed: true
|
|
1399
|
-
});
|
|
1400
|
-
break;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
// 选择最优折扣
|
|
1404
|
-
const nextSelectedDiscountCard = nextApplicableDiscounts.find(n => n.isScan && n.isSelected && (n.tag || n.type) !== 'good_pass');
|
|
1405
|
-
const nextSelectedDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
|
|
1406
|
-
|
|
1407
|
-
// 判断新折扣是否需要拆分
|
|
1408
|
-
const nextDiscType = nextSelectedDiscount.tag || nextSelectedDiscount.type;
|
|
1409
|
-
const nextIsGoodPass = nextDiscType === 'good_pass';
|
|
1410
|
-
const nextIsDiscountCard = ['discount_card', 'product_discount_card'].includes(nextDiscType);
|
|
1411
|
-
const nextApplicableProductLimit = nextSelectedDiscount.config?.applicableProductLimit || 0;
|
|
1412
|
-
const nextIsNeedSplit = nextIsGoodPass || nextIsDiscountCard && nextApplicableProductLimit > 0;
|
|
1413
|
-
if (!nextIsNeedSplit) {
|
|
1414
|
-
// 🔥 不需要拆分:直接应用折扣到所有剩余商品
|
|
1415
|
-
const nextBundleDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
|
|
1416
|
-
usedDiscounts.set(nextBundleDiscount.id, true);
|
|
1417
|
-
if ((nextBundleDiscount.tag || nextBundleDiscount.type) === 'good_pass') {
|
|
1418
|
-
const curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
|
|
1419
|
-
usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
|
|
1420
|
-
}
|
|
1421
|
-
const nextNoSplitType = nextBundleDiscount.tag || nextBundleDiscount.type;
|
|
1422
|
-
if (['discount_card', 'product_discount_card'].includes(nextNoSplitType)) {
|
|
1423
|
-
const curCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
|
|
1424
|
-
usedDiscountCardLimitCounts.set(nextBundleDiscount.id, curCount + remainingNum);
|
|
1425
|
-
}
|
|
1426
|
-
const nextOriginTotal = product.original_price || product.price || 0;
|
|
1427
|
-
const nextTargetTotal = (0, _utils.getDiscountAmount)(nextBundleDiscount, nextOriginTotal, nextOriginTotal);
|
|
1428
|
-
const nextDiscountAmount = new _decimal.default(nextOriginTotal).minus(nextTargetTotal).toNumber();
|
|
1429
|
-
const nextUniqueId = `${flatItem._id}_split_${continueSplitIndex}`;
|
|
1430
|
-
const nextBundleDiscType = nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : nextBundleDiscount.tag;
|
|
1431
|
-
const nextDiscountDetail = {
|
|
1432
|
-
amount: nextDiscountAmount * remainingNum,
|
|
1433
|
-
type: nextBundleDiscType,
|
|
1434
|
-
discount: {
|
|
1435
|
-
discount_card_type: nextBundleDiscount?.metadata?.discount_card_type,
|
|
1436
|
-
fixed_amount: nextDiscountAmount,
|
|
1437
|
-
resource_id: nextBundleDiscount.id,
|
|
1438
|
-
title: nextBundleDiscount.format_title,
|
|
1439
|
-
original_amount: product.original_price,
|
|
1440
|
-
product_id: product.id,
|
|
1441
|
-
percent: nextBundleDiscount.par_value,
|
|
1442
|
-
discount_product_id: nextBundleDiscount.product_id
|
|
1443
|
-
},
|
|
1444
|
-
metadata: {
|
|
1445
|
-
custom_product_bundle_map_id: nextUniqueId,
|
|
1446
|
-
num: remainingNum
|
|
1447
|
-
},
|
|
1448
|
-
config: nextBundleDiscount?.config,
|
|
1449
|
-
_num: remainingNum * (flatItem?.parentProduct?.num || 1)
|
|
1450
|
-
};
|
|
1451
|
-
const nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
|
|
1452
|
-
nextAppliedProducts.push(nextDiscountDetail);
|
|
1453
|
-
appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
|
|
1454
|
-
processedItems.push({
|
|
1455
|
-
...flatItem,
|
|
1456
|
-
_id: nextUniqueId,
|
|
1457
|
-
num: remainingNum,
|
|
1458
|
-
quantity: remainingNum,
|
|
1459
|
-
total: nextTargetTotal,
|
|
1460
|
-
price: new _decimal.default(nextOriginTotal || 0).minus(nextDiscountDetail.discount.fixed_amount).toNumber(),
|
|
1461
|
-
discount_list: [nextDiscountDetail],
|
|
1462
|
-
processed: true
|
|
1463
|
-
});
|
|
1464
|
-
remainingNum = 0;
|
|
1465
|
-
break;
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
// 🔥 需要拆分:计算最大使用次数
|
|
1469
|
-
let nextMaxUsageLimit;
|
|
1470
|
-
if (nextIsGoodPass) {
|
|
1471
|
-
const nextGoodPassCount = nextApplicableDiscounts.filter(item => (item.tag || item.type) === 'good_pass').length;
|
|
1472
|
-
nextMaxUsageLimit = nextGoodPassCount;
|
|
1473
|
-
if (nextSelectedDiscount.config?.maxUsagePerOrder) {
|
|
1474
|
-
const usedCount = usedProductIdCounts.get(nextSelectedDiscount.product_id) || 0;
|
|
1475
|
-
nextMaxUsageLimit = Math.min(nextGoodPassCount, Math.max(0, nextSelectedDiscount.config.maxUsagePerOrder - usedCount));
|
|
1476
|
-
}
|
|
1477
|
-
} else if (nextIsDiscountCard && nextApplicableProductLimit > 0) {
|
|
1478
|
-
const usedLimitCount = usedDiscountCardLimitCounts.get(nextSelectedDiscount.id) || 0;
|
|
1479
|
-
nextMaxUsageLimit = Math.max(0, nextApplicableProductLimit - usedLimitCount);
|
|
1480
|
-
} else {
|
|
1481
|
-
nextMaxUsageLimit = 1;
|
|
1482
|
-
}
|
|
1483
|
-
const nextSplitCount = Math.min(remainingNum, nextMaxUsageLimit);
|
|
1484
|
-
if (nextSplitCount === 0) {
|
|
1485
|
-
// 已达使用上限,剩余商品无折扣存储
|
|
1486
|
-
processedItems.push({
|
|
1487
|
-
...flatItem,
|
|
1488
|
-
_id: `${flatItem._id}_split_rest`,
|
|
1489
|
-
num: remainingNum,
|
|
1490
|
-
quantity: remainingNum,
|
|
1491
|
-
discount_list: [],
|
|
1492
|
-
processed: true
|
|
1493
|
-
});
|
|
1494
|
-
break;
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
// 生成有折扣的商品
|
|
1498
|
-
for (let j = 0; j < nextSplitCount; j++) {
|
|
1499
|
-
const nextBundleDiscount = nextIsGoodPass ? nextSelectedDiscountCard || nextApplicableDiscounts[j] : nextSelectedDiscountCard || nextApplicableDiscounts[0];
|
|
1500
|
-
usedDiscounts.set(nextBundleDiscount.id, true);
|
|
1501
|
-
if ((nextBundleDiscount.tag || nextBundleDiscount.type) === 'good_pass') {
|
|
1502
|
-
const curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
|
|
1503
|
-
usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
|
|
1504
|
-
}
|
|
1505
|
-
const nextBundleDiscTypeForCount = nextBundleDiscount.tag || nextBundleDiscount.type;
|
|
1506
|
-
if (['discount_card', 'product_discount_card'].includes(nextBundleDiscTypeForCount)) {
|
|
1507
|
-
const curLimitCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
|
|
1508
|
-
usedDiscountCardLimitCounts.set(nextBundleDiscount.id, curLimitCount + 1);
|
|
1509
|
-
}
|
|
1510
|
-
const nextUniqueId = `${flatItem._id}_split_${continueSplitIndex}`;
|
|
1511
|
-
const nextDiscountedPrice = (0, _utils.getDiscountAmount)(nextBundleDiscount, product.origin_total, product.origin_total);
|
|
1512
|
-
const nextBundleDiscAmount = new _decimal.default(product.origin_total || 0).minus(nextDiscountedPrice).toNumber();
|
|
1513
|
-
const nextBundleDiscTypeStr = nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : nextBundleDiscount.tag;
|
|
1514
|
-
const nextDiscountDetail = {
|
|
1515
|
-
amount: nextBundleDiscAmount,
|
|
1516
|
-
type: nextBundleDiscTypeStr,
|
|
1517
|
-
discount: {
|
|
1518
|
-
discount_card_type: nextBundleDiscount?.metadata?.discount_card_type,
|
|
1519
|
-
fixed_amount: nextBundleDiscAmount,
|
|
1520
|
-
resource_id: nextBundleDiscount.id,
|
|
1521
|
-
title: nextBundleDiscount.format_title,
|
|
1522
|
-
original_amount: product.origin_total,
|
|
1523
|
-
product_id: product.id,
|
|
1524
|
-
percent: nextBundleDiscount.par_value,
|
|
1525
|
-
discount_product_id: nextBundleDiscount.product_id
|
|
1526
|
-
},
|
|
1527
|
-
metadata: {
|
|
1528
|
-
custom_product_bundle_map_id: nextUniqueId,
|
|
1529
|
-
num: 1
|
|
1530
|
-
},
|
|
1531
|
-
_num: 1,
|
|
1532
|
-
config: nextBundleDiscount?.config
|
|
1533
|
-
};
|
|
1534
|
-
const nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
|
|
1535
|
-
nextAppliedProducts.push(nextDiscountDetail);
|
|
1536
|
-
appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
|
|
1537
|
-
processedItems.push({
|
|
1538
|
-
...flatItem,
|
|
1539
|
-
_id: nextUniqueId,
|
|
1540
|
-
num: 1,
|
|
1541
|
-
quantity: 1,
|
|
1542
|
-
price: nextDiscountedPrice,
|
|
1543
|
-
total: nextDiscountedPrice,
|
|
1544
|
-
discount_list: [nextDiscountDetail],
|
|
1545
|
-
processed: true,
|
|
1546
|
-
_discountId: nextBundleDiscount.id
|
|
1547
|
-
});
|
|
1548
|
-
continueSplitIndex++;
|
|
1549
|
-
}
|
|
1550
|
-
remainingNum -= nextSplitCount;
|
|
1551
1226
|
}
|
|
1552
1227
|
} else {
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
const currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
|
|
1559
|
-
usedProductIdCounts.set(currentBundleDiscount.product_id, currentCount + 1);
|
|
1560
|
-
}
|
|
1561
|
-
// 🔥 更新折扣卡 applicableProductLimit 使用计数(不拆分时按商品数量计数)
|
|
1562
|
-
const noSplitDiscountType = currentBundleDiscount.tag || currentBundleDiscount.type;
|
|
1563
|
-
if (['discount_card', 'product_discount_card'].includes(noSplitDiscountType)) {
|
|
1564
|
-
const bundleQuantity = product.num || 1;
|
|
1565
|
-
const currentNoSplitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
|
|
1566
|
-
usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentNoSplitCount + bundleQuantity);
|
|
1228
|
+
const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[0];
|
|
1229
|
+
usedDiscounts.set(selectedDiscount2.id, true);
|
|
1230
|
+
if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
|
|
1231
|
+
const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
|
|
1232
|
+
usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
|
|
1567
1233
|
}
|
|
1568
1234
|
const productOriginTotal = product.original_price || product.price || 0;
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
const
|
|
1572
|
-
const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
|
|
1573
|
-
const productAllocation = orderLevelAllocation?.get(flatItem._id);
|
|
1235
|
+
const isOrderLevel = (0, import_utils3.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
|
|
1236
|
+
const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
|
|
1237
|
+
const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
|
|
1574
1238
|
let targetProductTotal;
|
|
1575
1239
|
let fixedAmountPerItem;
|
|
1576
1240
|
let productDiscountDifference;
|
|
1577
1241
|
if (isOrderLevel && productAllocation) {
|
|
1578
|
-
// order_level:使用预计算的单价折扣金额(已经是单价,无需再除以数量)
|
|
1579
1242
|
fixedAmountPerItem = productAllocation.discountAmount;
|
|
1580
1243
|
productDiscountDifference = productAllocation.difference;
|
|
1581
|
-
targetProductTotal = Math.max(new
|
|
1244
|
+
targetProductTotal = Math.max(new import_decimal.default(productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
|
|
1582
1245
|
} else {
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1246
|
+
targetProductTotal = (0, import_utils.getDiscountAmount)(
|
|
1247
|
+
selectedDiscount2,
|
|
1248
|
+
productOriginTotal,
|
|
1249
|
+
productOriginTotal
|
|
1250
|
+
);
|
|
1251
|
+
fixedAmountPerItem = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
|
|
1586
1252
|
}
|
|
1587
|
-
|
|
1588
|
-
// 计算实际折扣金额
|
|
1589
|
-
const bundleActualDiscountAmount = new _decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
|
|
1590
|
-
|
|
1591
|
-
// 🔥 使用当前的 _id 作为唯一标识
|
|
1592
1253
|
const uniqueId = flatItem._id;
|
|
1254
|
+
debugger;
|
|
1593
1255
|
const discountDetail = {
|
|
1594
|
-
amount:
|
|
1595
|
-
type:
|
|
1256
|
+
amount: fixedAmountPerItem * (product.num || 1),
|
|
1257
|
+
type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag,
|
|
1596
1258
|
discount: {
|
|
1597
|
-
discount_card_type:
|
|
1598
|
-
fixed_amount:
|
|
1599
|
-
discount_calculation_mode:
|
|
1600
|
-
resource_id:
|
|
1601
|
-
title:
|
|
1259
|
+
discount_card_type: (_G = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _G.discount_card_type,
|
|
1260
|
+
fixed_amount: fixedAmountPerItem,
|
|
1261
|
+
discount_calculation_mode: (_H = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _H.discount_calculation_mode,
|
|
1262
|
+
resource_id: selectedDiscount2.id,
|
|
1263
|
+
title: selectedDiscount2.format_title,
|
|
1602
1264
|
original_amount: product.original_price,
|
|
1603
|
-
product_id: product.id,
|
|
1604
|
-
percent:
|
|
1605
|
-
discount_product_id:
|
|
1265
|
+
product_id: product.id || product.product_id,
|
|
1266
|
+
percent: selectedDiscount2.par_value,
|
|
1267
|
+
discount_product_id: selectedDiscount2.product_id
|
|
1606
1268
|
},
|
|
1607
1269
|
metadata: {
|
|
1608
1270
|
// 🔥 使用唯一的 _id
|
|
1609
1271
|
custom_product_bundle_map_id: uniqueId,
|
|
1610
|
-
discount_rule_uncheck_flag:
|
|
1272
|
+
discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
|
|
1611
1273
|
num: product.num || 1,
|
|
1612
1274
|
// 🔥 order_level 分摊差值
|
|
1613
|
-
...
|
|
1614
|
-
product_discount_difference: productDiscountDifference
|
|
1615
|
-
})
|
|
1275
|
+
...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
|
|
1616
1276
|
},
|
|
1617
|
-
config:
|
|
1618
|
-
_num: (product.num || 1) * (flatItem
|
|
1277
|
+
config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config,
|
|
1278
|
+
_num: (product.num || 1) * (((_I = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _I.num) || 1)
|
|
1619
1279
|
};
|
|
1620
|
-
|
|
1621
|
-
// 记录实际应用的折扣
|
|
1622
|
-
const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
|
|
1280
|
+
const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
|
|
1623
1281
|
appliedProducts.push(discountDetail);
|
|
1624
|
-
appliedDiscountProducts.set(
|
|
1282
|
+
appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
|
|
1625
1283
|
processedItems.push({
|
|
1626
1284
|
...flatItem,
|
|
1627
1285
|
total: targetProductTotal,
|
|
1628
|
-
price: new
|
|
1629
|
-
discount_list: this.filterDiscountListByType(flatItem.discount_list,
|
|
1286
|
+
price: new import_decimal.default(productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
|
|
1287
|
+
discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion").concat([discountDetail]),
|
|
1630
1288
|
processed: true
|
|
1631
1289
|
});
|
|
1632
1290
|
}
|
|
1633
1291
|
processedFlatItemsMap.set(flatItem._id, processedItems);
|
|
1634
1292
|
}
|
|
1635
1293
|
});
|
|
1636
|
-
|
|
1637
|
-
// 🔥 重组:将处理后的bundle子商品重新组装回主商品
|
|
1638
|
-
const reconstructProductsWithBundle = (processedProductsMap, processedFlatItemsMap, originalProductList) => {
|
|
1294
|
+
const reconstructProductsWithBundle = (processedProductsMap2, processedFlatItemsMap2, originalProductList) => {
|
|
1639
1295
|
const result = [];
|
|
1640
|
-
originalProductList.forEach(originProduct => {
|
|
1296
|
+
originalProductList.forEach((originProduct) => {
|
|
1641
1297
|
const product = this.hooks.getProduct(originProduct);
|
|
1642
|
-
|
|
1643
|
-
// 获取主商品处理结果
|
|
1644
|
-
const mainProductArr = processedProductsMap.get(product._id);
|
|
1298
|
+
const mainProductArr = processedProductsMap2.get(product._id);
|
|
1645
1299
|
if (!mainProductArr || mainProductArr.length === 0) {
|
|
1646
|
-
// 如果没有处理结果,返回默认商品(还原 option 价格)
|
|
1647
1300
|
const getDefaultProduct = () => {
|
|
1648
1301
|
const restoredOptions = restoreOptionPrices(product.options);
|
|
1649
1302
|
if (product.isClient) {
|
|
1650
1303
|
return this.hooks.setProduct(originProduct, {
|
|
1651
|
-
discount_list: this.filterDiscountListByType(product.discount_list,
|
|
1304
|
+
discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
|
|
1652
1305
|
price: product.price,
|
|
1653
|
-
origin_total: (0,
|
|
1306
|
+
origin_total: (0, import_utils2.getProductOriginTotalPrice)({
|
|
1654
1307
|
product: {
|
|
1655
1308
|
original_price: product.original_price
|
|
1656
1309
|
},
|
|
@@ -1659,7 +1312,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1659
1312
|
}),
|
|
1660
1313
|
variant: originProduct._productInit.variant,
|
|
1661
1314
|
original_price: originProduct._productInit.original_price,
|
|
1662
|
-
total: (0,
|
|
1315
|
+
total: (0, import_utils2.getProductTotalPrice)({
|
|
1663
1316
|
product: {
|
|
1664
1317
|
price: product.price
|
|
1665
1318
|
},
|
|
@@ -1670,7 +1323,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1670
1323
|
});
|
|
1671
1324
|
} else {
|
|
1672
1325
|
return this.hooks.setProduct(originProduct, {
|
|
1673
|
-
discount_list: this.filterDiscountListByType(product.discount_list,
|
|
1326
|
+
discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
|
|
1674
1327
|
total: product.total,
|
|
1675
1328
|
origin_total: product.origin_total,
|
|
1676
1329
|
price: product.price,
|
|
@@ -1681,360 +1334,325 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1681
1334
|
result.push(getDefaultProduct());
|
|
1682
1335
|
return;
|
|
1683
1336
|
}
|
|
1684
|
-
|
|
1685
|
-
// 检查是否有bundle子商品需要重组
|
|
1686
1337
|
const hasBundle = product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0;
|
|
1687
1338
|
if (!hasBundle) {
|
|
1688
|
-
// 没有bundle,直接使用主商品处理结果
|
|
1689
1339
|
result.push(...mainProductArr);
|
|
1690
1340
|
} else {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
const bundleProcessingInfo = new Map();
|
|
1694
|
-
let hasGoodPassApplied = false; // 标记是否有子商品应用了商品券
|
|
1695
|
-
|
|
1341
|
+
const bundleProcessingInfo = /* @__PURE__ */ new Map();
|
|
1342
|
+
let hasGoodPassApplied = false;
|
|
1696
1343
|
if (product.bundle && Array.isArray(product.bundle)) {
|
|
1697
1344
|
product.bundle.forEach((bundleItem, bundleIndex) => {
|
|
1698
1345
|
const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
|
|
1699
|
-
const processedBundleItems =
|
|
1346
|
+
const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
|
|
1700
1347
|
if (!processedBundleItems || processedBundleItems.length === 0) {
|
|
1701
|
-
// 未处理的bundle item,保持原样
|
|
1702
1348
|
bundleProcessingInfo.set(bundleIndex, [bundleItem]);
|
|
1703
1349
|
} else {
|
|
1704
|
-
// 处理过的bundle item
|
|
1705
1350
|
bundleProcessingInfo.set(bundleIndex, processedBundleItems);
|
|
1706
|
-
|
|
1707
|
-
|
|
1351
|
+
const hasGoodPass = processedBundleItems.some(
|
|
1352
|
+
(item) => {
|
|
1353
|
+
var _a2;
|
|
1354
|
+
return (_a2 = item.discount_list) == null ? void 0 : _a2.some(
|
|
1355
|
+
(discount) => discount.type === "good_pass" || discount.tag === "good_pass"
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
);
|
|
1708
1359
|
if (hasGoodPass) {
|
|
1709
1360
|
hasGoodPassApplied = true;
|
|
1710
1361
|
}
|
|
1711
1362
|
}
|
|
1712
1363
|
});
|
|
1713
1364
|
}
|
|
1714
|
-
|
|
1715
|
-
// 🔥 2. 如果有子商品应用了商品券,且主商品数量大于1,需要拆分主商品
|
|
1716
1365
|
const mainProductQuantity = mainProductArr[0] ? this.hooks.getProduct(mainProductArr[0]).quantity : 1;
|
|
1717
1366
|
if (hasGoodPassApplied && mainProductArr.length === 1 && mainProductQuantity > 1) {
|
|
1718
1367
|
const mainProduct = mainProductArr[0];
|
|
1719
1368
|
const mainProductData = this.hooks.getProduct(mainProduct);
|
|
1720
|
-
|
|
1721
|
-
// 🔥 方案:拆分成2个主商品
|
|
1722
|
-
// 1. 一个主商品(qty=1)包含拆分后的bundle
|
|
1723
|
-
// 2. 一个主商品(qty=原quantity-1)包含原始未拆分的bundle
|
|
1724
|
-
|
|
1725
|
-
// 第一个:包含拆分后的bundle (qty=1)
|
|
1726
1369
|
const newBundleWithDiscount = [];
|
|
1727
|
-
(product.bundle || []).forEach(
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
});
|
|
1752
|
-
} else {
|
|
1753
|
-
// 未拆分的子商品,保持原样
|
|
1754
|
-
const item = processedItems[0];
|
|
1755
|
-
if (item.processed) {
|
|
1756
|
-
// 🔥 同样需要更新 discount_list 中的 num
|
|
1757
|
-
const updatedDiscountList = (item.discount_list || []).map(discount => ({
|
|
1758
|
-
...discount,
|
|
1759
|
-
metadata: {
|
|
1760
|
-
...discount.metadata,
|
|
1370
|
+
(product.bundle || []).forEach(
|
|
1371
|
+
(bundleItem, bundleIndex) => {
|
|
1372
|
+
const processedItems = bundleProcessingInfo.get(
|
|
1373
|
+
bundleIndex
|
|
1374
|
+
) || [bundleItem];
|
|
1375
|
+
if (processedItems.length > 1) {
|
|
1376
|
+
processedItems.forEach((item) => {
|
|
1377
|
+
const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
|
|
1378
|
+
var _a2;
|
|
1379
|
+
return {
|
|
1380
|
+
...discount,
|
|
1381
|
+
metadata: {
|
|
1382
|
+
...discount.metadata,
|
|
1383
|
+
num: item.num,
|
|
1384
|
+
custom_product_bundle_map_id: (_a2 = item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
|
|
1385
|
+
}
|
|
1386
|
+
// num: item.num, // 使用拆分后的 num
|
|
1387
|
+
};
|
|
1388
|
+
});
|
|
1389
|
+
newBundleWithDiscount.push({
|
|
1390
|
+
...bundleItem,
|
|
1391
|
+
_id: item._id,
|
|
1392
|
+
product_id: bundleItem.product_id,
|
|
1393
|
+
price: item.price,
|
|
1761
1394
|
num: item.num,
|
|
1762
|
-
|
|
1763
|
-
}
|
|
1764
|
-
// num: item.num, // 使用当前的 num
|
|
1765
|
-
}));
|
|
1766
|
-
newBundleWithDiscount.push({
|
|
1767
|
-
...bundleItem,
|
|
1768
|
-
_id: item._id,
|
|
1769
|
-
product_id: bundleItem.product_id,
|
|
1770
|
-
price: item.price,
|
|
1771
|
-
num: item.num,
|
|
1772
|
-
quantity: item.num,
|
|
1773
|
-
discount_list: updatedDiscountList
|
|
1395
|
+
discount_list: updatedDiscountList2
|
|
1396
|
+
});
|
|
1774
1397
|
});
|
|
1775
1398
|
} else {
|
|
1776
|
-
|
|
1399
|
+
const item = processedItems[0];
|
|
1400
|
+
if (item.processed) {
|
|
1401
|
+
const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
|
|
1402
|
+
var _a2;
|
|
1403
|
+
return {
|
|
1404
|
+
...discount,
|
|
1405
|
+
metadata: {
|
|
1406
|
+
...discount.metadata,
|
|
1407
|
+
num: item.num,
|
|
1408
|
+
custom_product_bundle_map_id: (_a2 = item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
|
|
1409
|
+
}
|
|
1410
|
+
// num: item.num, // 使用当前的 num
|
|
1411
|
+
};
|
|
1412
|
+
});
|
|
1413
|
+
newBundleWithDiscount.push({
|
|
1414
|
+
...bundleItem,
|
|
1415
|
+
_id: item._id,
|
|
1416
|
+
product_id: bundleItem.product_id,
|
|
1417
|
+
price: item.price,
|
|
1418
|
+
num: item.num,
|
|
1419
|
+
discount_list: updatedDiscountList2
|
|
1420
|
+
});
|
|
1421
|
+
} else {
|
|
1422
|
+
newBundleWithDiscount.push(item);
|
|
1423
|
+
}
|
|
1777
1424
|
}
|
|
1778
1425
|
}
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
// 计算第一个主商品的总价(包含拆分后的bundle)
|
|
1426
|
+
);
|
|
1782
1427
|
let newTotalWithDiscount = Number(mainProductData.price || 0);
|
|
1783
|
-
let newOriginTotalWithDiscount = Number(
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
const updatedMainDiscountList = mainProductData.discount_list.map(discount => {
|
|
1787
|
-
|
|
1788
|
-
|
|
1428
|
+
let newOriginTotalWithDiscount = Number(
|
|
1429
|
+
mainProductData.original_price || mainProductData.price || 0
|
|
1430
|
+
);
|
|
1431
|
+
const updatedMainDiscountList = mainProductData.discount_list.map((discount) => {
|
|
1432
|
+
var _a2, _b;
|
|
1433
|
+
if ((_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id) {
|
|
1789
1434
|
return discount;
|
|
1790
1435
|
}
|
|
1791
|
-
// 主商品自己的discount,更新num为1
|
|
1792
1436
|
return {
|
|
1793
1437
|
...discount,
|
|
1794
1438
|
// num: 1,
|
|
1795
1439
|
metadata: {
|
|
1796
1440
|
...discount.metadata,
|
|
1797
|
-
custom_product_bundle_map_id: discount
|
|
1441
|
+
custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
|
|
1798
1442
|
num: 1
|
|
1799
1443
|
}
|
|
1800
1444
|
};
|
|
1801
1445
|
});
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1446
|
+
const mainDiscountList = updatedMainDiscountList.filter(
|
|
1447
|
+
(item) => {
|
|
1448
|
+
var _a2;
|
|
1449
|
+
return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
|
|
1450
|
+
}
|
|
1451
|
+
);
|
|
1805
1452
|
if (mainDiscountList && mainDiscountList.length > 0) {
|
|
1806
|
-
const allDiscountAmount = (0,
|
|
1807
|
-
newTotalWithDiscount = new
|
|
1453
|
+
const allDiscountAmount = (0, import_utils.getDiscountListAmountTotal)(mainDiscountList);
|
|
1454
|
+
newTotalWithDiscount = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalWithDiscount;
|
|
1808
1455
|
newOriginTotalWithDiscount = mainProductData.origin_total ?? newOriginTotalWithDiscount;
|
|
1809
1456
|
}
|
|
1810
|
-
|
|
1811
|
-
// 累加bundle的价格(只累加一次)
|
|
1812
1457
|
if (newBundleWithDiscount.length > 0) {
|
|
1813
|
-
newBundleWithDiscount.forEach(item => {
|
|
1458
|
+
newBundleWithDiscount.forEach((item) => {
|
|
1814
1459
|
newTotalWithDiscount += Number(item.price) * Number(item.num);
|
|
1815
1460
|
});
|
|
1816
|
-
newBundleWithDiscount.forEach(item => {
|
|
1817
|
-
|
|
1461
|
+
newBundleWithDiscount.forEach((item) => {
|
|
1462
|
+
var _a2, _b, _c;
|
|
1463
|
+
const originalPrice = ((_c = (_b = (_a2 = item.discount_list) == null ? void 0 : _a2[0]) == null ? void 0 : _b.discount) == null ? void 0 : _c.original_amount) || item.price;
|
|
1818
1464
|
newOriginTotalWithDiscount += Number(originalPrice) * Number(item.num);
|
|
1819
1465
|
});
|
|
1820
1466
|
}
|
|
1821
|
-
|
|
1822
|
-
// 累加options的价格(options不参与折扣,在最终设置total时处理)
|
|
1823
|
-
if (product?.options) {
|
|
1467
|
+
if (product == null ? void 0 : product.options) {
|
|
1824
1468
|
newTotalWithDiscount = product.options.reduce((accumulator, currentValue) => {
|
|
1825
|
-
const currentPrice = new
|
|
1826
|
-
const currentNum = new
|
|
1469
|
+
const currentPrice = new import_decimal.default(currentValue.price || 0);
|
|
1470
|
+
const currentNum = new import_decimal.default(currentValue.num || 0);
|
|
1827
1471
|
return accumulator.add(currentPrice.mul(currentNum));
|
|
1828
|
-
}, new
|
|
1472
|
+
}, new import_decimal.default(newTotalWithDiscount)).toNumber();
|
|
1829
1473
|
}
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
// 第二个:包含原始bundle (qty=原quantity-1)
|
|
1474
|
+
result.push(
|
|
1475
|
+
this.hooks.setProduct(mainProduct, {
|
|
1476
|
+
...mainProductData,
|
|
1477
|
+
_id: `${mainProductData._id.split("___")[0]}___split_discount`,
|
|
1478
|
+
quantity: 1,
|
|
1479
|
+
discount_list: updatedMainDiscountList,
|
|
1480
|
+
bundle: newBundleWithDiscount,
|
|
1481
|
+
total: new import_decimal.default(newTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
|
|
1482
|
+
origin_total: new import_decimal.default(newOriginTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
|
|
1483
|
+
})
|
|
1484
|
+
);
|
|
1843
1485
|
if (mainProductQuantity > 1) {
|
|
1844
1486
|
const newBundleOriginal = [];
|
|
1845
|
-
(product.bundle || []).forEach(
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
// 计算第二个主商品的总价
|
|
1487
|
+
(product.bundle || []).forEach(
|
|
1488
|
+
(bundleItem, bundleIndex) => {
|
|
1489
|
+
newBundleOriginal.push({
|
|
1490
|
+
...bundleItem,
|
|
1491
|
+
discount_list: []
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1854
1495
|
let newTotalOriginal = Number(mainProductData.price || 0);
|
|
1855
|
-
let newOriginTotalOriginal = Number(
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
const updatedMainDiscountListOriginal = mainProductData.discount_list.map(discount => {
|
|
1859
|
-
|
|
1860
|
-
|
|
1496
|
+
let newOriginTotalOriginal = Number(
|
|
1497
|
+
mainProductData.original_price || mainProductData.price || 0
|
|
1498
|
+
);
|
|
1499
|
+
const updatedMainDiscountListOriginal = mainProductData.discount_list.map((discount) => {
|
|
1500
|
+
var _a2, _b;
|
|
1501
|
+
if ((_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id) {
|
|
1861
1502
|
return discount;
|
|
1862
1503
|
}
|
|
1863
|
-
// 主商品自己的discount,更新num为 mainProductQuantity - 1
|
|
1864
1504
|
return {
|
|
1865
1505
|
...discount,
|
|
1866
1506
|
metadata: {
|
|
1867
1507
|
...discount.metadata,
|
|
1868
1508
|
num: mainProductQuantity - 1,
|
|
1869
|
-
custom_product_bundle_map_id: discount
|
|
1509
|
+
custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id
|
|
1870
1510
|
}
|
|
1871
1511
|
// num: mainProductQuantity - 1,
|
|
1872
1512
|
};
|
|
1873
1513
|
});
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1514
|
+
const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter(
|
|
1515
|
+
(item) => {
|
|
1516
|
+
var _a2;
|
|
1517
|
+
return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
|
|
1518
|
+
}
|
|
1519
|
+
);
|
|
1877
1520
|
if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
|
|
1878
|
-
const allDiscountAmount = (0,
|
|
1879
|
-
|
|
1521
|
+
const allDiscountAmount = (0, import_utils.getDiscountListAmount)(
|
|
1522
|
+
mainDiscountListOriginal
|
|
1523
|
+
);
|
|
1524
|
+
newTotalOriginal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalOriginal;
|
|
1880
1525
|
newOriginTotalOriginal = mainProductData.origin_total ?? newOriginTotalOriginal;
|
|
1881
1526
|
}
|
|
1882
|
-
|
|
1883
|
-
// 累加bundle的价格(只累加一次)
|
|
1884
1527
|
if (newBundleOriginal.length > 0) {
|
|
1885
|
-
newBundleOriginal.forEach(item => {
|
|
1528
|
+
newBundleOriginal.forEach((item) => {
|
|
1886
1529
|
newTotalOriginal += Number(item.price) * Number(item.num);
|
|
1887
1530
|
newOriginTotalOriginal += Number(item.price) * Number(item.num);
|
|
1888
1531
|
});
|
|
1889
1532
|
}
|
|
1890
|
-
|
|
1891
|
-
// 累加options的价格(options不参与折扣,在最终设置total时处理)
|
|
1892
|
-
if (product?.options) {
|
|
1533
|
+
if (product == null ? void 0 : product.options) {
|
|
1893
1534
|
newTotalOriginal = product.options.reduce((accumulator, currentValue) => {
|
|
1894
|
-
const currentPrice = new
|
|
1895
|
-
const currentNum = new
|
|
1535
|
+
const currentPrice = new import_decimal.default(currentValue.price || 0);
|
|
1536
|
+
const currentNum = new import_decimal.default(currentValue.num || 0);
|
|
1896
1537
|
return accumulator.add(currentPrice.mul(currentNum));
|
|
1897
|
-
}, new
|
|
1538
|
+
}, new import_decimal.default(newTotalOriginal)).toNumber();
|
|
1898
1539
|
}
|
|
1899
|
-
newTotalOriginal = new
|
|
1900
|
-
newOriginTotalOriginal = new
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1540
|
+
newTotalOriginal = new import_decimal.default(newTotalOriginal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
1541
|
+
newOriginTotalOriginal = new import_decimal.default(newOriginTotalOriginal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
1542
|
+
result.push(
|
|
1543
|
+
this.hooks.setProduct(mainProduct, {
|
|
1544
|
+
...mainProductData,
|
|
1545
|
+
_id: `${mainProductData._id.split("___")[0]}___split_normal`,
|
|
1546
|
+
quantity: mainProductQuantity - 1,
|
|
1547
|
+
discount_list: updatedMainDiscountListOriginal,
|
|
1548
|
+
bundle: newBundleOriginal,
|
|
1549
|
+
total: newTotalOriginal,
|
|
1550
|
+
origin_total: newOriginTotalOriginal
|
|
1551
|
+
})
|
|
1552
|
+
);
|
|
1912
1553
|
}
|
|
1913
1554
|
} else {
|
|
1914
|
-
|
|
1915
|
-
|
|
1555
|
+
mainProductArr.forEach((mainProduct) => {
|
|
1556
|
+
var _a2, _b, _c;
|
|
1916
1557
|
const mainProductData = this.hooks.getProduct(mainProduct);
|
|
1917
|
-
|
|
1918
|
-
// 重组bundle
|
|
1919
1558
|
const newBundle = [];
|
|
1920
1559
|
if (product.bundle && Array.isArray(product.bundle)) {
|
|
1921
1560
|
product.bundle.forEach((bundleItem, bundleIndex) => {
|
|
1922
1561
|
const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
|
|
1923
|
-
const processedBundleItems =
|
|
1562
|
+
const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
|
|
1924
1563
|
if (!processedBundleItems || processedBundleItems.length === 0) {
|
|
1925
|
-
// 未处理的bundle item,保持原样
|
|
1926
1564
|
newBundle.push(bundleItem);
|
|
1927
1565
|
} else {
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
const
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
...discount
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1566
|
+
processedBundleItems.forEach((item) => {
|
|
1567
|
+
const nextBundlePrice = item.price ?? bundleItem.price;
|
|
1568
|
+
const nextBundleSellingPrice = item.bundle_selling_price ?? item.price ?? bundleItem.bundle_selling_price;
|
|
1569
|
+
const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
|
|
1570
|
+
var _a3;
|
|
1571
|
+
return {
|
|
1572
|
+
...discount,
|
|
1573
|
+
metadata: {
|
|
1574
|
+
...discount.metadata,
|
|
1575
|
+
num: item.num,
|
|
1576
|
+
custom_product_bundle_map_id: (_a3 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a3.custom_product_bundle_map_id
|
|
1577
|
+
}
|
|
1578
|
+
// num: item.num, // 使用拆分后的 num
|
|
1579
|
+
};
|
|
1580
|
+
});
|
|
1940
1581
|
newBundle.push({
|
|
1941
1582
|
...bundleItem,
|
|
1942
1583
|
_id: item._id,
|
|
1943
1584
|
product_id: bundleItem.product_id,
|
|
1944
|
-
price:
|
|
1585
|
+
price: nextBundlePrice,
|
|
1945
1586
|
num: item.num,
|
|
1946
|
-
discount_list:
|
|
1947
|
-
bundle_selling_price: bundleItem.bundle_selling_price !==
|
|
1587
|
+
discount_list: updatedDiscountList2,
|
|
1588
|
+
bundle_selling_price: bundleItem.bundle_selling_price !== void 0 ? nextBundleSellingPrice : void 0
|
|
1948
1589
|
});
|
|
1949
1590
|
});
|
|
1950
1591
|
}
|
|
1951
1592
|
});
|
|
1952
1593
|
}
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
let newTotal = Number(mainProductData.price || 0);
|
|
1594
|
+
const mainSellingPrice = mainProductData.main_product_selling_price ?? mainProductData.price ?? 0;
|
|
1595
|
+
let newTotal = Number(mainSellingPrice || 0);
|
|
1956
1596
|
let newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
|
|
1957
|
-
|
|
1958
|
-
// 判断是否是手动折扣
|
|
1959
|
-
const isManualDiscount = typeof mainProductData.isManualDiscount === 'boolean' ? mainProductData.isManualDiscount : mainProductData.total != mainProductData.origin_total && (!mainProductData.discount_list?.length || mainProductData?.discount_list?.every?.(item => item.type === 'product'));
|
|
1960
|
-
|
|
1961
|
-
// 如果是手动折扣,使用原有的total和origin_total,不重新计算
|
|
1597
|
+
const isManualDiscount = typeof mainProductData.isManualDiscount === "boolean" ? mainProductData.isManualDiscount : mainProductData.total != mainProductData.origin_total && (!((_a2 = mainProductData.discount_list) == null ? void 0 : _a2.length) || ((_c = (_b = mainProductData == null ? void 0 : mainProductData.discount_list) == null ? void 0 : _b.every) == null ? void 0 : _c.call(_b, (item) => item.type === "product")));
|
|
1962
1598
|
if (isManualDiscount) {
|
|
1963
1599
|
newTotal = mainProductData.total ?? newTotal;
|
|
1964
1600
|
newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
|
|
1965
1601
|
} else {
|
|
1966
|
-
// 不是手动折扣时,才重新计算
|
|
1967
|
-
const mainDiscountList = mainProductData.discount_list.filter(item => !item?.metadata?.custom_product_bundle_map_id);
|
|
1968
|
-
|
|
1969
|
-
// 如果主商品本身有折扣,需要重新计算主商品价格
|
|
1970
|
-
if (mainDiscountList && mainDiscountList.length > 0) {
|
|
1971
|
-
const allDiscountAmount = (0, _utils.getDiscountListAmount)(mainDiscountList);
|
|
1972
|
-
newTotal = new _decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotal;
|
|
1973
|
-
newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
|
|
1974
|
-
}
|
|
1975
|
-
|
|
1976
|
-
// 累加bundle的价格(只累加一次)
|
|
1977
1602
|
if (newBundle.length > 0) {
|
|
1978
|
-
newBundle.forEach(item => {
|
|
1979
|
-
|
|
1980
|
-
|
|
1603
|
+
newBundle.forEach((item) => {
|
|
1604
|
+
const bundleSellingPrice = item.bundle_selling_price ?? item.price;
|
|
1605
|
+
newTotal += Number(bundleSellingPrice) * Number(item.num);
|
|
1606
|
+
});
|
|
1607
|
+
newBundle.forEach((item) => {
|
|
1608
|
+
var _a3, _b2, _c2;
|
|
1609
|
+
const originalPrice = ((_c2 = (_b2 = (_a3 = item.discount_list) == null ? void 0 : _a3[0]) == null ? void 0 : _b2.discount) == null ? void 0 : _c2.original_amount) || item.price;
|
|
1981
1610
|
newOriginTotal += Number(originalPrice) * Number(item.num);
|
|
1982
1611
|
});
|
|
1983
1612
|
}
|
|
1984
1613
|
}
|
|
1985
|
-
|
|
1986
|
-
// 累加options的价格(options不参与折扣,在最终设置total时处理)
|
|
1987
|
-
if (product?.options) {
|
|
1614
|
+
if (product == null ? void 0 : product.options) {
|
|
1988
1615
|
newTotal = product.options.reduce((accumulator, currentValue) => {
|
|
1989
|
-
const currentPrice = new
|
|
1990
|
-
const currentNum = new
|
|
1616
|
+
const currentPrice = new import_decimal.default(currentValue.price || 0);
|
|
1617
|
+
const currentNum = new import_decimal.default(currentValue.num || 0);
|
|
1991
1618
|
return accumulator.add(currentPrice.mul(currentNum));
|
|
1992
|
-
}, new
|
|
1619
|
+
}, new import_decimal.default(newTotal)).toNumber();
|
|
1993
1620
|
}
|
|
1994
|
-
newTotal = new
|
|
1995
|
-
newOriginTotal = new
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
1621
|
+
newTotal = new import_decimal.default(newTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
1622
|
+
newOriginTotal = new import_decimal.default(newOriginTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
|
|
1623
|
+
result.push(
|
|
1624
|
+
this.hooks.setProduct(mainProduct, {
|
|
1625
|
+
...mainProductData,
|
|
1626
|
+
bundle: newBundle,
|
|
1627
|
+
total: newTotal,
|
|
1628
|
+
origin_total: newOriginTotal
|
|
1629
|
+
})
|
|
1630
|
+
);
|
|
2004
1631
|
});
|
|
2005
1632
|
}
|
|
2006
1633
|
}
|
|
2007
1634
|
});
|
|
2008
1635
|
return result;
|
|
2009
1636
|
};
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
const updatedDiscountList = addModeDiscount.map(discount => {
|
|
2016
|
-
// 获取此优惠券适用的商品列表
|
|
1637
|
+
const processedProductList = reconstructProductsWithBundle(
|
|
1638
|
+
processedProductsMap,
|
|
1639
|
+
processedFlatItemsMap,
|
|
1640
|
+
productList
|
|
1641
|
+
);
|
|
1642
|
+
const updatedDiscountList = addModeDiscount.map((discount) => {
|
|
2017
1643
|
const applicableProducts = discountApplicability.get(discount.id) || [];
|
|
2018
|
-
|
|
2019
|
-
// 获取此优惠券适用的商品详情
|
|
2020
1644
|
const applicableProductDetails = discountApplicableProducts.get(discount.id) || [];
|
|
2021
|
-
|
|
2022
|
-
// 获取此优惠券实际应用的商品详情
|
|
2023
1645
|
const appliedProductDetails = appliedDiscountProducts.get(discount.id) || [];
|
|
2024
|
-
|
|
2025
|
-
// 根据是否有适用商品决定isAvailable
|
|
2026
1646
|
const isAvailable = applicableProducts.length > 0;
|
|
2027
|
-
|
|
2028
|
-
// 如果此优惠券被明确设置为不选中,保持其状态,但正确设置isAvailable
|
|
2029
|
-
if (typeof discount.isSelected === 'boolean' && discount.isSelected === false && discount.isManualSelect) {
|
|
1647
|
+
if (typeof discount.isSelected === "boolean" && discount.isSelected === false && discount.isManualSelect) {
|
|
2030
1648
|
return {
|
|
2031
1649
|
...discount,
|
|
2032
1650
|
isSelected: false,
|
|
2033
|
-
isAvailable
|
|
1651
|
+
isAvailable,
|
|
2034
1652
|
// 正确设置可用性
|
|
2035
1653
|
applicableProductIds: applicableProducts,
|
|
2036
1654
|
// 添加可抵扣的商品详情
|
|
2037
|
-
applicableProductDetails
|
|
1655
|
+
applicableProductDetails,
|
|
2038
1656
|
// 添加实际抵扣的商品详情(对于未选中的优惠券,为空数组)
|
|
2039
1657
|
appliedProductDetails: []
|
|
2040
1658
|
};
|
|
@@ -2043,20 +1661,18 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
2043
1661
|
return {
|
|
2044
1662
|
...discount,
|
|
2045
1663
|
isSelected: true,
|
|
2046
|
-
isManualSelect: options
|
|
1664
|
+
isManualSelect: (options == null ? void 0 : options.scan) ? false : discount.isManualSelect,
|
|
2047
1665
|
// 标记为可用,因为它已被应用
|
|
2048
1666
|
isAvailable: true,
|
|
2049
1667
|
// 记录适用的商品IDs
|
|
2050
1668
|
applicableProductIds: applicableProducts,
|
|
2051
1669
|
// 添加可抵扣的商品详情
|
|
2052
|
-
applicableProductDetails
|
|
1670
|
+
applicableProductDetails,
|
|
2053
1671
|
// 添加实际抵扣的商品详情
|
|
2054
|
-
appliedProductDetails
|
|
1672
|
+
appliedProductDetails
|
|
2055
1673
|
};
|
|
2056
1674
|
}
|
|
2057
|
-
let isSelected = typeof discount.isSelected ===
|
|
2058
|
-
|
|
2059
|
-
// 如果是可用的 并且没有手动标记 则设置为选中
|
|
1675
|
+
let isSelected = typeof discount.isSelected === "boolean" ? discount.isSelected : void 0;
|
|
2060
1676
|
if (isAvailable && appliedProductDetails.length && !discount.isManualSelect) {
|
|
2061
1677
|
isSelected = true;
|
|
2062
1678
|
} else if (!appliedProductDetails.length) {
|
|
@@ -2065,14 +1681,14 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
2065
1681
|
return {
|
|
2066
1682
|
...discount,
|
|
2067
1683
|
// 如果有适用的商品,标记为可用
|
|
2068
|
-
isAvailable
|
|
1684
|
+
isAvailable,
|
|
2069
1685
|
isSelected,
|
|
2070
1686
|
// 如果是扫码进来的,要手动设置为手动选择:false
|
|
2071
|
-
isManualSelect: options
|
|
1687
|
+
isManualSelect: (options == null ? void 0 : options.scan) ? false : discount.isManualSelect,
|
|
2072
1688
|
// 记录适用的商品IDs
|
|
2073
1689
|
applicableProductIds: applicableProducts,
|
|
2074
1690
|
// 添加可抵扣的商品详情
|
|
2075
|
-
applicableProductDetails
|
|
1691
|
+
applicableProductDetails,
|
|
2076
1692
|
// 添加实际抵扣的商品详情(对于未使用的优惠券,为空数组)
|
|
2077
1693
|
appliedProductDetails: []
|
|
2078
1694
|
};
|
|
@@ -2082,7 +1698,6 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
2082
1698
|
discountList: [...editModeDiscount, ...updatedDiscountList]
|
|
2083
1699
|
};
|
|
2084
1700
|
}
|
|
2085
|
-
|
|
2086
1701
|
/**
|
|
2087
1702
|
* 检查优惠是否符合 PackageSubItemUsageRules 配置
|
|
2088
1703
|
* @param discount 优惠券
|
|
@@ -2090,200 +1705,105 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
2090
1705
|
* @returns 是否可用
|
|
2091
1706
|
*/
|
|
2092
1707
|
checkPackageSubItemUsageRules(discount, flatItem) {
|
|
1708
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2093
1709
|
const limitedData = discount.limited_relation_product_data;
|
|
2094
|
-
const usageRules = limitedData
|
|
2095
|
-
const rules = [
|
|
2096
|
-
|
|
2097
|
-
// 如果没有配置 package_sub_item_usage_rules,则默认可用
|
|
1710
|
+
const usageRules = limitedData == null ? void 0 : limitedData.package_sub_item_usage_rules;
|
|
1711
|
+
const rules = ["original_price", ...(usageRules == null ? void 0 : usageRules.rules) || []];
|
|
2098
1712
|
if (!usageRules) {
|
|
2099
1713
|
return true;
|
|
2100
1714
|
}
|
|
2101
1715
|
const ruleType = usageRules.type;
|
|
2102
|
-
|
|
2103
|
-
const
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
include_bundle_product_ids = [],
|
|
2108
|
-
filter = 0
|
|
2109
|
-
} = packageScope || {};
|
|
2110
|
-
const isMainProduct = flatItem.type === 'main'; // 单独购买
|
|
2111
|
-
const isBundleItem = flatItem.type === 'bundle'; // 套餐中购买
|
|
2112
|
-
|
|
2113
|
-
// 主商品直接可用
|
|
1716
|
+
const packageScope = usageRules == null ? void 0 : usageRules.package_scope;
|
|
1717
|
+
const { type: scopeType, exclude_bundle_product_ids = [], include_bundle_product_ids = [], filter = 0 } = packageScope || {};
|
|
1718
|
+
const isMainProduct = flatItem.type === "main";
|
|
1719
|
+
const isBundleItem = flatItem.type === "bundle";
|
|
1720
|
+
const bundleMainProductId = (_a = flatItem.product) == null ? void 0 : _a.product_id;
|
|
2114
1721
|
if (isMainProduct) {
|
|
2115
1722
|
return true;
|
|
2116
1723
|
}
|
|
2117
|
-
|
|
2118
|
-
// universal_discount: 单独购买和套餐中(子商品为原价)均可使用
|
|
2119
|
-
if (ruleType === 'universal_discount') {
|
|
1724
|
+
if (ruleType === "universal_discount") {
|
|
2120
1725
|
if (isMainProduct) {
|
|
2121
|
-
return true;
|
|
1726
|
+
return true;
|
|
2122
1727
|
}
|
|
2123
1728
|
if (isBundleItem) {
|
|
2124
|
-
|
|
2125
|
-
const
|
|
2126
|
-
const
|
|
2127
|
-
|
|
2128
|
-
const
|
|
2129
|
-
// original_price 对应:
|
|
2130
|
-
// 1. price_type: "markup" && price_type_ext: "product_price"
|
|
2131
|
-
// markup_price 对应:
|
|
2132
|
-
// price_type: "markup" && price_type_ext: ""
|
|
2133
|
-
/** 原价 */
|
|
2134
|
-
const isOriginalPrice = priceType === 'markup' && priceTypeExt === 'product_price';
|
|
2135
|
-
/** 加价 */
|
|
2136
|
-
const isMarkupPrice = priceType === 'markup' && (priceTypeExt === '' || !priceTypeExt);
|
|
2137
|
-
|
|
2138
|
-
// 检查 rules
|
|
1729
|
+
const priceType = (_b = flatItem.bundleItem) == null ? void 0 : _b.price_type;
|
|
1730
|
+
const priceTypeExt = (_c = flatItem.bundleItem) == null ? void 0 : _c.price_type_ext;
|
|
1731
|
+
const mainProductId = ((_e = (_d = flatItem == null ? void 0 : flatItem.originProduct) == null ? void 0 : _d._productOrigin) == null ? void 0 : _e.id) || ((_f = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _f.id) || 0;
|
|
1732
|
+
const isOriginalPrice = priceType === "markup" && priceTypeExt === "product_price";
|
|
1733
|
+
const isMarkupPrice = priceType === "markup" && (priceTypeExt === "" || !priceTypeExt);
|
|
2139
1734
|
if (rules.length > 0) {
|
|
2140
|
-
const _isOriginalPrice = isOriginalPrice && rules.includes(
|
|
2141
|
-
const _isMarkupPrice = isMarkupPrice && rules.includes(
|
|
2142
|
-
// 价格是否符合规则:原价或加价
|
|
1735
|
+
const _isOriginalPrice = isOriginalPrice && rules.includes("original_price");
|
|
1736
|
+
const _isMarkupPrice = isMarkupPrice && rules.includes("markup_price");
|
|
2143
1737
|
const isPriceValid = _isOriginalPrice || _isMarkupPrice;
|
|
2144
|
-
// 套餐适用范围校验
|
|
2145
1738
|
let isScopeValid = false;
|
|
2146
|
-
|
|
2147
|
-
// 排除套餐判断, product_all值兼容旧数据
|
|
2148
|
-
if (scopeType === 'all_packages' || scopeType === 'product_all') {
|
|
2149
|
-
// 所有套餐可用
|
|
1739
|
+
if (scopeType === "all_packages" || scopeType === "product_all") {
|
|
2150
1740
|
if (!filter) {
|
|
2151
1741
|
isScopeValid = true;
|
|
2152
1742
|
} else {
|
|
2153
|
-
isScopeValid = !exclude_bundle_product_ids.includes(Number(
|
|
1743
|
+
isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
|
|
2154
1744
|
}
|
|
2155
1745
|
}
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
if (scopeType === 'specific_packages' || scopeType === 'products') {
|
|
2159
|
-
isScopeValid = include_bundle_product_ids.includes(Number(mainProductId));
|
|
1746
|
+
if (scopeType === "specific_packages" || scopeType === "products") {
|
|
1747
|
+
isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
|
|
2160
1748
|
}
|
|
2161
|
-
|
|
2162
|
-
// 价格和套餐适用范围都符合,则可用
|
|
2163
1749
|
if (isPriceValid && isScopeValid) {
|
|
2164
1750
|
return true;
|
|
2165
1751
|
}
|
|
2166
|
-
|
|
2167
|
-
// 检查原价
|
|
2168
|
-
// if (isOriginalPrice && rules.includes('original_price')) {
|
|
2169
|
-
// return true;
|
|
2170
|
-
// }
|
|
2171
|
-
|
|
2172
|
-
// 检查加价
|
|
2173
|
-
// if (isMarkupPrice && rules.includes('markup_price')) {
|
|
2174
|
-
// return true;
|
|
2175
|
-
// }
|
|
2176
|
-
|
|
2177
|
-
// 如果都不匹配,则不可用
|
|
2178
1752
|
return false;
|
|
2179
1753
|
}
|
|
2180
|
-
|
|
2181
|
-
// 原价包括:price_type: "markup" && price_type_ext: "product_price"
|
|
2182
1754
|
return isOriginalPrice;
|
|
2183
1755
|
}
|
|
2184
1756
|
return true;
|
|
2185
1757
|
}
|
|
2186
|
-
|
|
2187
|
-
// package_exclusive: 仅在套餐中(子商品为原价)时可使用
|
|
2188
|
-
if (ruleType === 'package_exclusive') {
|
|
1758
|
+
if (ruleType === "package_exclusive") {
|
|
2189
1759
|
if (isMainProduct) {
|
|
2190
|
-
return false;
|
|
1760
|
+
return false;
|
|
2191
1761
|
}
|
|
2192
1762
|
if (isBundleItem) {
|
|
2193
|
-
|
|
2194
|
-
const
|
|
2195
|
-
const
|
|
2196
|
-
|
|
2197
|
-
// original_price 对应:
|
|
2198
|
-
// 1. price_type: "markup" && price_type_ext: "product_price"
|
|
2199
|
-
// markup_price 对应:
|
|
2200
|
-
// price_type: "markup" && price_type_ext: ""
|
|
2201
|
-
/** 原价 */
|
|
2202
|
-
const isOriginalPrice = priceType === 'markup' && priceTypeExt === 'product_price';
|
|
2203
|
-
/** 加价 */
|
|
2204
|
-
const isMarkupPrice = priceType === 'markup' && (priceTypeExt === '' || !priceTypeExt);
|
|
2205
|
-
|
|
2206
|
-
// 检查 rules
|
|
1763
|
+
const priceType = (_g = flatItem.bundleItem) == null ? void 0 : _g.price_type;
|
|
1764
|
+
const priceTypeExt = (_h = flatItem.bundleItem) == null ? void 0 : _h.price_type_ext;
|
|
1765
|
+
const isOriginalPrice = priceType === "markup" && priceTypeExt === "product_price";
|
|
1766
|
+
const isMarkupPrice = priceType === "markup" && (priceTypeExt === "" || !priceTypeExt);
|
|
2207
1767
|
if (rules.length > 0) {
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
1768
|
+
const _isOriginalPrice = isOriginalPrice && rules.includes("original_price");
|
|
1769
|
+
const _isMarkupPrice = isMarkupPrice && rules.includes("markup_price");
|
|
1770
|
+
const isPriceValid = _isOriginalPrice || _isMarkupPrice;
|
|
1771
|
+
let isScopeValid = false;
|
|
1772
|
+
if (scopeType === "all_packages" || scopeType === "product_all") {
|
|
1773
|
+
if (!filter) {
|
|
1774
|
+
isScopeValid = true;
|
|
1775
|
+
} else {
|
|
1776
|
+
isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
|
|
1777
|
+
}
|
|
2211
1778
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
1779
|
+
if (scopeType === "specific_packages" || scopeType === "products") {
|
|
1780
|
+
isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
|
|
1781
|
+
}
|
|
1782
|
+
if (isPriceValid && isScopeValid) {
|
|
2215
1783
|
return true;
|
|
2216
1784
|
}
|
|
2217
|
-
|
|
2218
|
-
// 如果都不匹配,则不可用
|
|
2219
1785
|
return false;
|
|
2220
1786
|
}
|
|
2221
|
-
|
|
2222
|
-
// 原价包括:price_type: "markup" && price_type_ext: "product_price"
|
|
2223
1787
|
return isOriginalPrice;
|
|
2224
1788
|
}
|
|
2225
1789
|
return false;
|
|
2226
1790
|
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
if (ruleType === 'single_item_promo') {
|
|
2230
|
-
return isMainProduct; // 只有单独购买时可用
|
|
1791
|
+
if (ruleType === "single_item_promo") {
|
|
1792
|
+
return isMainProduct;
|
|
2231
1793
|
}
|
|
2232
|
-
|
|
2233
|
-
/*
|
|
2234
|
-
// custom_usage_rules: 根据自定义规则判断
|
|
2235
|
-
if (ruleType === 'custom_usage_rules') {
|
|
2236
|
-
const customRules = usageRules.custom_usage_rules;
|
|
2237
|
-
if (!customRules) {
|
|
2238
|
-
return true; // 如果没有自定义规则,默认可用
|
|
2239
|
-
}
|
|
2240
|
-
const { types, package_sub_item_rules } = customRules;
|
|
2241
|
-
// 判断商品类型是否在允许的类型中
|
|
2242
|
-
if (isMainProduct) {
|
|
2243
|
-
// 主商品对应 standalone_product
|
|
2244
|
-
if (!types.includes('standalone_product')) {
|
|
2245
|
-
return false;
|
|
2246
|
-
}
|
|
2247
|
-
return true; // 主商品不需要判断 package_sub_item_rules
|
|
2248
|
-
}
|
|
2249
|
-
if (isBundleItem) {
|
|
2250
|
-
// bundle子商品对应 package_sub_item
|
|
2251
|
-
if (!types.includes('package_sub_item')) {
|
|
2252
|
-
return false;
|
|
2253
|
-
}
|
|
2254
|
-
// 如果包含 package_sub_item,还需要判断 price_type
|
|
2255
|
-
const priceType = flatItem.bundleItem?.price_type;
|
|
2256
|
-
const priceTypeExt = flatItem.bundleItem?.price_type_ext;
|
|
2257
|
-
// 检查 package_sub_item_rules
|
|
2258
|
-
if (package_sub_item_rules && package_sub_item_rules.length > 0) {
|
|
2259
|
-
// original_price 对应:
|
|
2260
|
-
// 1. price_type: "markup" && price_type_ext: "product_price"
|
|
2261
|
-
// markup_price 对应:
|
|
2262
|
-
// price_type: "markup" && price_type_ext: ""
|
|
2263
|
-
const isOriginalPrice = (priceType === 'markup' && priceTypeExt === 'product_price');
|
|
2264
|
-
const isMarkupPrice = priceType === 'markup' && (priceTypeExt === '' || !priceTypeExt);
|
|
2265
|
-
if (isOriginalPrice && package_sub_item_rules.includes('original_price')) {
|
|
2266
|
-
return true;
|
|
2267
|
-
}
|
|
2268
|
-
if (isMarkupPrice && package_sub_item_rules.includes('markup_price')) {
|
|
2269
|
-
return true;
|
|
2270
|
-
}
|
|
2271
|
-
// 如果都不匹配,则不可用
|
|
2272
|
-
return false;
|
|
2273
|
-
}
|
|
2274
|
-
return true; // 如果没有 package_sub_item_rules 配置,默认可用
|
|
2275
|
-
}
|
|
2276
|
-
return true;
|
|
2277
|
-
}
|
|
2278
|
-
* */
|
|
2279
|
-
|
|
2280
|
-
// 默认可用
|
|
2281
1794
|
return true;
|
|
2282
1795
|
}
|
|
2283
1796
|
async destroy() {
|
|
2284
1797
|
this.core.effects.offByModuleDestroy(this.name);
|
|
2285
1798
|
await this.core.effects.emit(`${this.name}:onDestroy`, {});
|
|
1799
|
+
console.log("[Rules] 已销毁");
|
|
1800
|
+
super.destroy();
|
|
1801
|
+
}
|
|
1802
|
+
async clear() {
|
|
1803
|
+
console.log("[Rules] clear");
|
|
2286
1804
|
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
exports
|
|
1805
|
+
};
|
|
1806
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1807
|
+
0 && (module.exports = {
|
|
1808
|
+
RulesModule
|
|
1809
|
+
});
|