@pisell/pisellos 2.2.244 → 2.2.245
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/model/strategy/adapter/walletPass/utils.js +7 -4
- package/dist/modules/BookingContext/index.d.ts +48 -0
- package/dist/modules/BookingContext/index.js +566 -0
- package/dist/modules/BookingContext/types.d.ts +102 -0
- package/dist/modules/BookingContext/types.js +51 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +284 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +145 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +218 -0
- package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/dist/modules/BookingContext/utils/flexible.js +56 -0
- package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
- package/dist/modules/BookingContext/utils/index.d.ts +11 -0
- package/dist/modules/BookingContext/utils/index.js +11 -0
- package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/dist/modules/BookingContext/utils/noResource.js +77 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts +1 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.js +36 -0
- package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/dist/modules/BookingContext/utils/productExtend.js +339 -0
- package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
- package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
- package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
- package/dist/modules/BookingContext/utils/resources.js +486 -0
- package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
- package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
- package/dist/modules/Cart/utils/cartProduct.js +24 -3
- 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/Discount/index.d.ts +1 -1
- package/dist/modules/Discount/index.js +13 -6
- package/dist/modules/Discount/types.d.ts +1 -0
- package/dist/modules/OpenData/index.d.ts +8 -0
- package/dist/modules/OpenData/index.js +37 -17
- package/dist/modules/Order/index.d.ts +275 -19
- package/dist/modules/Order/index.js +3493 -809
- package/dist/modules/Order/types.d.ts +286 -31
- package/dist/modules/Order/types.js +38 -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.d.ts +147 -5
- package/dist/modules/Order/utils.js +750 -104
- package/dist/modules/Payment/index.d.ts +10 -13
- package/dist/modules/Payment/index.js +467 -837
- package/dist/modules/Payment/types.d.ts +2 -0
- package/dist/modules/Payment/utils.js +2 -1
- package/dist/modules/Payment/walletpass.js +41 -25
- package/dist/modules/ProductList/index.d.ts +16 -12
- package/dist/modules/ProductList/index.js +133 -59
- package/dist/modules/ProductList/types.d.ts +14 -0
- package/dist/modules/Quotation/index.d.ts +0 -1
- package/dist/modules/Quotation/index.js +25 -22
- package/dist/modules/Rules/index.d.ts +4 -0
- package/dist/modules/Rules/index.js +97 -70
- package/dist/modules/Rules/types.d.ts +1 -0
- package/dist/modules/SalesSummary/index.d.ts +8 -25
- package/dist/modules/SalesSummary/index.js +86 -35
- package/dist/modules/SalesSummary/types.d.ts +4 -1
- package/dist/modules/SalesSummary/utils.d.ts +2 -25
- package/dist/modules/SalesSummary/utils.js +794 -162
- package/dist/modules/Schedule/index.d.ts +7 -0
- package/dist/modules/Schedule/index.js +24 -2
- package/dist/modules/Summary/index.js +4 -3
- package/dist/modules/SurchargeList/index.d.ts +16 -0
- package/dist/modules/SurchargeList/index.js +162 -0
- package/dist/modules/SurchargeList/types.d.ts +11 -0
- package/dist/modules/SurchargeList/types.js +1 -0
- package/dist/modules/index.d.ts +2 -0
- package/dist/modules/index.js +3 -1
- package/dist/plugins/request.d.ts +1 -0
- package/dist/server/index.d.ts +204 -1
- package/dist/server/index.js +3654 -922
- package/dist/server/modules/index.d.ts +2 -0
- package/dist/server/modules/index.js +2 -0
- package/dist/server/modules/order/index.d.ts +120 -3
- package/dist/server/modules/order/index.js +1758 -448
- package/dist/server/modules/order/types.d.ts +32 -3
- package/dist/server/modules/order/types.js +8 -0
- package/dist/server/modules/order/utils/filterBookings.js +26 -3
- package/dist/server/modules/order/utils/filterOrders.js +23 -8
- 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 +34 -7
- package/dist/server/modules/products/index.js +631 -317
- package/dist/server/modules/resource/index.d.ts +2 -0
- package/dist/server/modules/resource/index.js +29 -3
- package/dist/server/modules/schedule/index.d.ts +4 -4
- package/dist/server/modules/schedule/index.js +111 -88
- package/dist/server/test.json +713 -0
- package/dist/server/utils/small-ticket.d.ts +71 -0
- package/dist/server/utils/small-ticket.js +840 -0
- package/dist/solution/BaseSales/index.d.ts +133 -10
- package/dist/solution/BaseSales/index.js +1950 -447
- package/dist/solution/BaseSales/types.d.ts +82 -6
- package/dist/solution/BaseSales/types.js +5 -4
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
- package/dist/solution/BaseSales/utils/cartPromotion.js +1438 -0
- package/dist/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
- package/dist/solution/BaseSales/utils/quotationPrice.js +237 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +105 -24
- package/dist/solution/BaseSales/utils.d.ts +1 -1
- package/dist/solution/BaseSales/utils.js +62 -21
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +271 -11
- package/dist/solution/BookingTicket/index.js +1777 -242
- package/dist/solution/BookingTicket/types.d.ts +118 -1
- package/dist/solution/BookingTicket/types.js +41 -2
- 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 +40 -0
- package/dist/solution/BookingTicket/utils/bookingStatus.js +70 -0
- package/dist/solution/BookingTicket/utils/cartView.d.ts +9 -1
- package/dist/solution/BookingTicket/utils/cartView.js +94 -7
- package/dist/solution/BookingTicket/utils/exampleData.d.ts +123 -0
- package/dist/solution/BookingTicket/utils/exampleData.js +183 -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/formatGlobalScan.d.ts +32 -0
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +20 -8
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts +23 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.js +78 -0
- package/dist/solution/Checkout/index.d.ts +1 -0
- package/dist/solution/Checkout/index.js +10 -9
- package/dist/solution/RegisterAndLogin/config.js +2 -10
- package/dist/solution/ScanOrder/index.d.ts +9 -3
- package/dist/solution/ScanOrder/index.js +241 -134
- package/dist/solution/ScanOrder/types.d.ts +9 -5
- package/dist/solution/ScanOrder/types.js +2 -3
- package/dist/solution/ScanOrder/utils.d.ts +1 -1
- package/dist/solution/ScanOrder/utils.js +84 -22
- package/dist/solution/VenueBooking/index.d.ts +5 -2
- package/dist/solution/VenueBooking/index.js +110 -59
- package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +10 -0
- package/dist/types/index.d.ts +10 -0
- package/lib/model/strategy/adapter/promotion/evaluator.js +2 -1
- package/lib/model/strategy/adapter/promotion/index.js +49 -0
- package/lib/model/strategy/adapter/walletPass/utils.js +3 -2
- 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 +276 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +151 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +76 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +201 -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/utils/cartProduct.js +20 -3
- package/lib/modules/Cart/utils/changePrice.js +12 -20
- package/lib/modules/Customer/index.d.ts +20 -0
- package/lib/modules/Customer/index.js +64 -11
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Discount/index.d.ts +1 -1
- package/lib/modules/Discount/index.js +9 -1
- package/lib/modules/Discount/types.d.ts +1 -0
- package/lib/modules/OpenData/index.d.ts +8 -0
- package/lib/modules/OpenData/index.js +19 -5
- package/lib/modules/Order/index.d.ts +275 -19
- package/lib/modules/Order/index.js +2245 -336
- package/lib/modules/Order/types.d.ts +286 -31
- package/lib/modules/Order/types.js +1 -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.d.ts +147 -5
- package/lib/modules/Order/utils.js +615 -46
- package/lib/modules/Payment/index.d.ts +10 -13
- package/lib/modules/Payment/index.js +18 -150
- package/lib/modules/Payment/types.d.ts +2 -0
- package/lib/modules/Payment/utils.js +2 -1
- package/lib/modules/Payment/walletpass.js +16 -3
- package/lib/modules/ProductList/index.d.ts +16 -12
- package/lib/modules/ProductList/index.js +41 -4
- package/lib/modules/ProductList/types.d.ts +14 -0
- package/lib/modules/Quotation/index.d.ts +0 -1
- package/lib/modules/Quotation/index.js +19 -16
- package/lib/modules/Rules/index.d.ts +4 -0
- package/lib/modules/Rules/index.js +137 -120
- package/lib/modules/Rules/types.d.ts +1 -0
- package/lib/modules/SalesSummary/index.d.ts +8 -25
- package/lib/modules/SalesSummary/index.js +30 -4
- package/lib/modules/SalesSummary/types.d.ts +4 -1
- package/lib/modules/SalesSummary/utils.d.ts +2 -25
- package/lib/modules/SalesSummary/utils.js +645 -91
- package/lib/modules/Schedule/index.d.ts +7 -0
- package/lib/modules/Schedule/index.js +17 -1
- package/lib/modules/Summary/index.js +5 -4
- package/lib/modules/SurchargeList/index.d.ts +16 -0
- package/lib/modules/SurchargeList/index.js +89 -0
- package/lib/modules/SurchargeList/types.d.ts +11 -0
- package/lib/modules/SurchargeList/types.js +17 -0
- package/lib/modules/index.d.ts +2 -0
- package/lib/modules/index.js +5 -1
- package/lib/plugins/request.d.ts +1 -0
- package/lib/server/index.d.ts +204 -1
- package/lib/server/index.js +1891 -59
- package/lib/server/modules/index.d.ts +2 -0
- package/lib/server/modules/index.js +3 -0
- package/lib/server/modules/order/index.d.ts +120 -3
- package/lib/server/modules/order/index.js +883 -94
- package/lib/server/modules/order/types.d.ts +32 -3
- package/lib/server/modules/order/utils/filterBookings.js +24 -5
- package/lib/server/modules/order/utils/filterOrders.js +15 -6
- 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 +34 -7
- package/lib/server/modules/products/index.js +189 -54
- package/lib/server/modules/resource/index.d.ts +2 -0
- package/lib/server/modules/resource/index.js +27 -3
- package/lib/server/modules/schedule/index.d.ts +4 -4
- package/lib/server/modules/schedule/index.js +47 -40
- package/lib/server/test.json +713 -0
- package/lib/server/utils/small-ticket.d.ts +71 -0
- package/lib/server/utils/small-ticket.js +800 -0
- package/lib/solution/BaseSales/index.d.ts +133 -10
- package/lib/solution/BaseSales/index.js +1111 -63
- package/lib/solution/BaseSales/types.d.ts +82 -6
- package/lib/solution/BaseSales/types.js +3 -1
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +287 -0
- package/lib/solution/BaseSales/utils/cartPromotion.js +992 -0
- package/lib/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
- package/lib/solution/BaseSales/utils/quotationPrice.js +277 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +106 -18
- package/lib/solution/BaseSales/utils.d.ts +1 -1
- package/lib/solution/BaseSales/utils.js +54 -10
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +271 -11
- package/lib/solution/BookingTicket/index.js +922 -29
- package/lib/solution/BookingTicket/types.d.ts +118 -1
- package/lib/solution/BookingTicket/types.js +11 -0
- 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 +40 -0
- package/lib/solution/BookingTicket/utils/bookingStatus.js +44 -2
- package/lib/solution/BookingTicket/utils/cartView.d.ts +9 -1
- package/lib/solution/BookingTicket/utils/cartView.js +61 -6
- package/lib/solution/BookingTicket/utils/exampleData.d.ts +123 -0
- package/lib/solution/BookingTicket/utils/exampleData.js +0 -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/formatGlobalScan.d.ts +32 -0
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +17 -3
- 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/Checkout/index.d.ts +1 -0
- package/lib/solution/Checkout/index.js +1 -2
- package/lib/solution/RegisterAndLogin/config.js +2 -10
- package/lib/solution/ScanOrder/index.d.ts +9 -3
- package/lib/solution/ScanOrder/index.js +153 -70
- package/lib/solution/ScanOrder/types.d.ts +9 -5
- package/lib/solution/ScanOrder/utils.d.ts +1 -1
- package/lib/solution/ScanOrder/utils.js +83 -17
- package/lib/solution/VenueBooking/index.d.ts +5 -2
- package/lib/solution/VenueBooking/index.js +54 -17
- package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -2
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +10 -0
- package/lib/types/index.d.ts +10 -0
- package/package.json +1 -1
- package/dist/solution/Checkout/appointmentDemo.json +0 -1
- package/lib/solution/Checkout/appointmentDemo.json +0 -1
|
@@ -37,37 +37,157 @@ var import_types = require("./types");
|
|
|
37
37
|
var import_utils = require("./utils");
|
|
38
38
|
var import_utils2 = require("../Product/utils");
|
|
39
39
|
var import_dayjs = __toESM(require("dayjs"));
|
|
40
|
+
var import_cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
|
|
40
41
|
var import_utils3 = require("../../solution/ScanOrder/utils");
|
|
42
|
+
var import_manualProductDiscount = require("./utils/manualProductDiscount");
|
|
41
43
|
var import_Discount = require("../Discount");
|
|
42
44
|
var import_Rules = require("../Rules");
|
|
43
45
|
var import_types2 = require("../Rules/types");
|
|
44
46
|
var import_decimal = __toESM(require("decimal.js"));
|
|
45
47
|
var import_lodash_es = require("lodash-es");
|
|
46
|
-
|
|
48
|
+
function normalizeDiscountListSignature(discountList) {
|
|
49
|
+
return (discountList || []).map((item) => ({
|
|
50
|
+
type: (item == null ? void 0 : item.type) ?? "",
|
|
51
|
+
discount_id: (item == null ? void 0 : item.discount_id) ?? null,
|
|
52
|
+
order_discount_id: (item == null ? void 0 : item.order_discount_id) ?? null,
|
|
53
|
+
amount: new import_decimal.default(Number(item == null ? void 0 : item.amount) || 0).toFixed(2)
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
function isSameDiscountList(left, right) {
|
|
57
|
+
if (!Array.isArray(left) || !Array.isArray(right))
|
|
58
|
+
return false;
|
|
59
|
+
return JSON.stringify(normalizeDiscountListSignature(left)) === JSON.stringify(
|
|
60
|
+
normalizeDiscountListSignature(right)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function isManualProductDiscountProduct(product) {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_manual_discount) === true || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_manual_discount) === 1 || ((product == null ? void 0 : product.discount_list) || []).some((item) => (item == null ? void 0 : item.type) === "product");
|
|
66
|
+
}
|
|
47
67
|
var OrderModule = class extends import_BaseModule.BaseModule {
|
|
48
68
|
constructor(name, version) {
|
|
49
69
|
super(name || "order", version);
|
|
50
70
|
this.defaultName = "order";
|
|
51
71
|
this.defaultVersion = "1.0.0";
|
|
72
|
+
// ─── 促销/赠品 ────────────────────────────────────
|
|
73
|
+
/** 评估器引用;由 SalesSdkProvider 注入,未注入时 applyPromotion 静默跳过 */
|
|
74
|
+
this.promotionEvaluator = null;
|
|
75
|
+
/** 赠品选择 resolver;由 SDK host bridge 注入 */
|
|
76
|
+
this.giftSelectResolver = null;
|
|
77
|
+
/** applyPromotion 递归保护 flag(写路径同步调 applyPromotion,禁止重入) */
|
|
78
|
+
this.isApplyingPromotion = false;
|
|
79
|
+
/** 最近一次 applyPromotion 的未满足促销提示 */
|
|
80
|
+
this.lastUnfulfilledPromotions = [];
|
|
81
|
+
/** 最近一次 applyPromotion 的赠品操作 diff(debug / SDK 读取使用) */
|
|
82
|
+
this.lastGiftActions = null;
|
|
83
|
+
/**
|
|
84
|
+
* 是否将 tempOrder 写入 IndexedDB 草稿(orders store)。
|
|
85
|
+
* BigSale 弹窗等短生命周期场景通过 setEnableTempOrderPersist(false) 关闭。
|
|
86
|
+
*/
|
|
87
|
+
this.draftPersistEnabled = true;
|
|
88
|
+
}
|
|
89
|
+
collectHydratedEditDiscounts(products) {
|
|
90
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
91
|
+
const discountMap = /* @__PURE__ */ new Map();
|
|
92
|
+
for (const product of products || []) {
|
|
93
|
+
for (const item of (product == null ? void 0 : product.discount_list) || []) {
|
|
94
|
+
const type = (item == null ? void 0 : item.type) ?? (item == null ? void 0 : item.tag);
|
|
95
|
+
if (!type || type === "product")
|
|
96
|
+
continue;
|
|
97
|
+
const resourceId = ((_a = item == null ? void 0 : item.discount) == null ? void 0 : _a.resource_id) ?? (item == null ? void 0 : item.resource_id) ?? (item == null ? void 0 : item.discount_id) ?? (item == null ? void 0 : item.order_discount_id);
|
|
98
|
+
if (resourceId === void 0 || resourceId === null || resourceId === "")
|
|
99
|
+
continue;
|
|
100
|
+
const id = Number(resourceId);
|
|
101
|
+
const key = Number.isFinite(id) ? id : String(resourceId);
|
|
102
|
+
const title = ((_b = item == null ? void 0 : item.discount) == null ? void 0 : _b.title) ?? {};
|
|
103
|
+
const amount = Number((item == null ? void 0 : item.amount) || 0);
|
|
104
|
+
const detail = {
|
|
105
|
+
amount: String((item == null ? void 0 : item.amount) ?? "0"),
|
|
106
|
+
type,
|
|
107
|
+
resource_id: key,
|
|
108
|
+
title,
|
|
109
|
+
original_amount: String(((_c = item == null ? void 0 : item.discount) == null ? void 0 : _c.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
|
|
110
|
+
num: Number(((_d = item == null ? void 0 : item.metadata) == null ? void 0 : _d.num) ?? (product == null ? void 0 : product.num) ?? (product == null ? void 0 : product.product_quantity) ?? 1) || 1,
|
|
111
|
+
metadata: item == null ? void 0 : item.metadata,
|
|
112
|
+
discount: item == null ? void 0 : item.discount,
|
|
113
|
+
_num: Number(((_e = item == null ? void 0 : item.metadata) == null ? void 0 : _e.num) ?? (product == null ? void 0 : product.num) ?? (product == null ? void 0 : product.product_quantity) ?? 1) || 1
|
|
114
|
+
};
|
|
115
|
+
discountMap.set(key, {
|
|
116
|
+
id: key,
|
|
117
|
+
product_name: "",
|
|
118
|
+
encoded: "",
|
|
119
|
+
code: "",
|
|
120
|
+
tag: type,
|
|
121
|
+
product_id: ((_f = item == null ? void 0 : item.discount) == null ? void 0 : _f.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
|
|
122
|
+
relation_type: "",
|
|
123
|
+
par_value: String(((_g = item == null ? void 0 : item.discount) == null ? void 0 : _g.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
|
|
124
|
+
used_par_value: String((item == null ? void 0 : item.amount) ?? "0"),
|
|
125
|
+
limit_status: "enable",
|
|
126
|
+
limited_relation_product_data: {
|
|
127
|
+
id: 0,
|
|
128
|
+
type: "products",
|
|
129
|
+
product_ids: [product == null ? void 0 : product.product_id].filter((value) => value !== void 0 && value !== null),
|
|
130
|
+
product_collection_id: [],
|
|
131
|
+
filter: 0,
|
|
132
|
+
exclude_product_ids: []
|
|
133
|
+
},
|
|
134
|
+
balance: String((item == null ? void 0 : item.amount) ?? "0"),
|
|
135
|
+
format_title: title,
|
|
136
|
+
product: {
|
|
137
|
+
id: (product == null ? void 0 : product.product_id) ?? 0,
|
|
138
|
+
title: "",
|
|
139
|
+
is_charge_tax: (product == null ? void 0 : product.is_charge_tax) ?? 0,
|
|
140
|
+
base_price: String((product == null ? void 0 : product.original_price) ?? (product == null ? void 0 : product.selling_price) ?? "0")
|
|
141
|
+
},
|
|
142
|
+
type,
|
|
143
|
+
resource_id: key,
|
|
144
|
+
isEditMode: true,
|
|
145
|
+
isSelected: true,
|
|
146
|
+
isAvailable: true,
|
|
147
|
+
isUsed: true,
|
|
148
|
+
isDisabled: true,
|
|
149
|
+
amount,
|
|
150
|
+
discount: {
|
|
151
|
+
...(item == null ? void 0 : item.discount) || {},
|
|
152
|
+
resource_id: key,
|
|
153
|
+
discount_product_id: ((_h = item == null ? void 0 : item.discount) == null ? void 0 : _h.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
|
|
154
|
+
discount_calculation_mode: ((_i = item == null ? void 0 : item.discount) == null ? void 0 : _i.discount_calculation_mode) ?? "item_level"
|
|
155
|
+
},
|
|
156
|
+
applicableProductDetails: [detail],
|
|
157
|
+
appliedProductDetails: [detail]
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return Array.from(discountMap.values());
|
|
52
162
|
}
|
|
53
163
|
/**
|
|
54
164
|
* Populate `savedAmount` on each discount based on product-level discount details.
|
|
55
165
|
* Only selected discounts get a non-zero value.
|
|
56
166
|
*/
|
|
57
167
|
static populateSavedAmounts(productList, discountList) {
|
|
58
|
-
var _a, _b;
|
|
59
168
|
const savedMap = /* @__PURE__ */ new Map();
|
|
169
|
+
const addDiscountAmount = (discount, quantity) => {
|
|
170
|
+
var _a, _b;
|
|
171
|
+
const discountKey = ((_a = discount.discount) == null ? void 0 : _a.resource_id) || discount.id;
|
|
172
|
+
if (discountKey == null)
|
|
173
|
+
return;
|
|
174
|
+
const qty = Number(quantity) || 1;
|
|
175
|
+
const amount = new import_decimal.default(discount.amount || 0).times(qty).plus(((_b = discount.metadata) == null ? void 0 : _b.product_discount_difference) || 0);
|
|
176
|
+
savedMap.set(
|
|
177
|
+
discountKey,
|
|
178
|
+
(savedMap.get(discountKey) || new import_decimal.default(0)).plus(amount)
|
|
179
|
+
);
|
|
180
|
+
};
|
|
60
181
|
for (const product of productList) {
|
|
61
182
|
const qty = product.num || 1;
|
|
62
183
|
for (const pd of product.discount_list || []) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
);
|
|
184
|
+
addDiscountAmount(pd, qty);
|
|
185
|
+
}
|
|
186
|
+
for (const bundle of product.product_bundle || []) {
|
|
187
|
+
const bundleQty = new import_decimal.default(Number(qty) || 1).times(Number((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity) ?? 1) || 1).toNumber();
|
|
188
|
+
for (const pd of (bundle == null ? void 0 : bundle.discount_list) || []) {
|
|
189
|
+
addDiscountAmount(pd, bundleQty);
|
|
190
|
+
}
|
|
71
191
|
}
|
|
72
192
|
}
|
|
73
193
|
for (const d of discountList) {
|
|
@@ -75,6 +195,32 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
75
195
|
d.savedAmount = d.isSelected && key != null && savedMap.has(key) ? savedMap.get(key).toNumber() : 0;
|
|
76
196
|
}
|
|
77
197
|
}
|
|
198
|
+
applyProductDiscountPrices(products) {
|
|
199
|
+
return (products || []).map((product) => {
|
|
200
|
+
var _a, _b;
|
|
201
|
+
if (isManualProductDiscountProduct(product))
|
|
202
|
+
return product;
|
|
203
|
+
const discountItems = Array.isArray(product.discount_list) ? product.discount_list : [];
|
|
204
|
+
const hasOnlyPersistedDiscountSnapshots = product.order_detail_id !== void 0 && product.order_detail_id !== null && discountItems.length > 0 && discountItems.every((discount) => (discount == null ? void 0 : discount.order_discount_id) !== void 0 && (discount == null ? void 0 : discount.order_discount_id) !== null);
|
|
205
|
+
if (hasOnlyPersistedDiscountSnapshots) {
|
|
206
|
+
return product;
|
|
207
|
+
}
|
|
208
|
+
const totalPerUnitDiscount = (0, import_utils.resolveEffectivePerUnitDiscount)(product);
|
|
209
|
+
const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
|
|
210
|
+
const sourcePrice = ((_a = product.metadata) == null ? void 0 : _a.source_product_price) ?? (((_b = product.metadata) == null ? void 0 : _b.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
|
|
211
|
+
const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
|
|
212
|
+
const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
213
|
+
if (product.metadata) {
|
|
214
|
+
product.metadata.main_product_selling_price = newMainSellingPrice;
|
|
215
|
+
product.metadata.price_schema_version = 2;
|
|
216
|
+
}
|
|
217
|
+
product.selling_price = (0, import_utils.composeLinePrice)({
|
|
218
|
+
mainPrice: newMainSellingPrice,
|
|
219
|
+
bundle: product.product_bundle
|
|
220
|
+
});
|
|
221
|
+
return product;
|
|
222
|
+
});
|
|
223
|
+
}
|
|
78
224
|
async initialize(core, options) {
|
|
79
225
|
var _a, _b, _c;
|
|
80
226
|
this.core = core;
|
|
@@ -92,18 +238,54 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
92
238
|
}
|
|
93
239
|
const app = appPlugin.getApp();
|
|
94
240
|
this.logger = app.logger;
|
|
95
|
-
this.dbManager = app.sqlite;
|
|
96
241
|
this.window = this.core.getPlugin("window");
|
|
97
242
|
const otherParams = options.otherParams || {};
|
|
98
243
|
this.cacheId = otherParams.cacheId;
|
|
99
244
|
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
100
245
|
this.rulesHooksOverride = (_a = otherParams.rules) == null ? void 0 : _a.hooks;
|
|
101
|
-
this.
|
|
246
|
+
this.moduleHooksOverride = options.hooks;
|
|
247
|
+
this.orderHooks = this.moduleHooksOverride || ((_b = otherParams.order) == null ? void 0 : _b.hooks) || ((_c = otherParams.hooks) == null ? void 0 : _c.order);
|
|
102
248
|
this.otherParams = otherParams;
|
|
103
249
|
this.registerDiscountModules(options);
|
|
104
|
-
this.restoreTempOrderFromStorage();
|
|
105
250
|
this.logInfo("OrderModule initialized successfully");
|
|
106
251
|
}
|
|
252
|
+
async destroy() {
|
|
253
|
+
var _a, _b;
|
|
254
|
+
const childModules = [(_a = this.store) == null ? void 0 : _a.discount, (_b = this.store) == null ? void 0 : _b.rules];
|
|
255
|
+
for (const childModule of childModules) {
|
|
256
|
+
if (!childModule || typeof childModule.destroy !== "function")
|
|
257
|
+
continue;
|
|
258
|
+
try {
|
|
259
|
+
await childModule.destroy();
|
|
260
|
+
} catch (error) {
|
|
261
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
262
|
+
this.logWarning("Destroy child module failed", {
|
|
263
|
+
module: childModule.name,
|
|
264
|
+
error: errorMessage
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (this.store) {
|
|
269
|
+
this.store.discount = null;
|
|
270
|
+
this.store.rules = null;
|
|
271
|
+
}
|
|
272
|
+
super.destroy();
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* 更新父级解决方案透传的运行态参数,并同步 Order 内部依赖的派生字段。
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* orderModule.updateOtherParams({ cacheId: 'cache-2', channel: 'pos' });
|
|
279
|
+
*/
|
|
280
|
+
updateOtherParams(params) {
|
|
281
|
+
var _a, _b, _c;
|
|
282
|
+
const otherParams = params || {};
|
|
283
|
+
this.cacheId = otherParams.cacheId;
|
|
284
|
+
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
285
|
+
this.rulesHooksOverride = (_a = otherParams.rules) == null ? void 0 : _a.hooks;
|
|
286
|
+
this.orderHooks = this.moduleHooksOverride || ((_b = otherParams.order) == null ? void 0 : _b.hooks) || ((_c = otherParams.hooks) == null ? void 0 : _c.order);
|
|
287
|
+
this.otherParams = otherParams;
|
|
288
|
+
}
|
|
107
289
|
/**
|
|
108
290
|
* 记录信息日志
|
|
109
291
|
*/
|
|
@@ -174,26 +356,57 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
174
356
|
}
|
|
175
357
|
// ─── Discount: 公共 API ───
|
|
176
358
|
async loadDiscountConfig(params) {
|
|
177
|
-
var _a, _b, _c, _d;
|
|
178
|
-
const
|
|
359
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
360
|
+
const orderId = params.orderId || ((_a = this.store.tempOrder) == null ? void 0 : _a.order_id) || void 0;
|
|
361
|
+
const discountList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
|
|
179
362
|
customer_id: params.customerId,
|
|
180
|
-
action: params.action || "create",
|
|
363
|
+
action: params.action || (orderId ? "edit" : "create"),
|
|
181
364
|
with_good_pass: 1,
|
|
182
365
|
with_discount_card: 1,
|
|
183
366
|
with_wallet_pass_holder: 1,
|
|
184
|
-
request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
367
|
+
request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
368
|
+
...orderId ? { order_id: orderId } : {}
|
|
185
369
|
}));
|
|
186
370
|
if (discountList) {
|
|
187
|
-
(
|
|
371
|
+
const currentEditDiscounts = (((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || []).filter((discount) => discount == null ? void 0 : discount.isEditMode);
|
|
372
|
+
const currentEditDiscountIds = new Set(
|
|
373
|
+
currentEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
|
|
374
|
+
);
|
|
375
|
+
const mergedDiscountList = [
|
|
376
|
+
...currentEditDiscounts,
|
|
377
|
+
...discountList.filter((discount) => !currentEditDiscountIds.has(discount == null ? void 0 : discount.id))
|
|
378
|
+
];
|
|
379
|
+
await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(mergedDiscountList));
|
|
380
|
+
await ((_e = this.store.discount) == null ? void 0 : _e.setDiscountList(mergedDiscountList));
|
|
188
381
|
}
|
|
189
|
-
if ((
|
|
382
|
+
if (params.apply !== false && ((_g = (_f = this.store.tempOrder) == null ? void 0 : _f.products) == null ? void 0 : _g.length)) {
|
|
190
383
|
this.applyDiscount();
|
|
191
384
|
}
|
|
385
|
+
return this.getDiscountList();
|
|
192
386
|
}
|
|
193
387
|
getDiscountList() {
|
|
194
388
|
var _a;
|
|
195
389
|
return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
|
|
196
390
|
}
|
|
391
|
+
async ensureEditDiscountConfigForProductChange(tempOrder) {
|
|
392
|
+
var _a, _b, _c, _d, _e, _f;
|
|
393
|
+
const orderId = tempOrder.order_id;
|
|
394
|
+
const customerId = Number(
|
|
395
|
+
tempOrder.customer_id || ((_a = tempOrder.customer) == null ? void 0 : _a.id) || ((_c = (_b = tempOrder._extend) == null ? void 0 : _b.customerSnapshot) == null ? void 0 : _c.id) || ((_e = (_d = tempOrder._extend) == null ? void 0 : _d.customerSnapshot) == null ? void 0 : _e.customer_id) || 0
|
|
396
|
+
);
|
|
397
|
+
if (!orderId || !customerId || customerId === 1)
|
|
398
|
+
return;
|
|
399
|
+
const currentDiscountList = ((_f = this.store.discount) == null ? void 0 : _f.getDiscountList()) || [];
|
|
400
|
+
const hasRuntimeDiscounts = currentDiscountList.some((discount) => !(discount == null ? void 0 : discount.isEditMode));
|
|
401
|
+
if (hasRuntimeDiscounts)
|
|
402
|
+
return;
|
|
403
|
+
await this.loadDiscountConfig({
|
|
404
|
+
customerId,
|
|
405
|
+
action: "edit",
|
|
406
|
+
orderId: Number(orderId),
|
|
407
|
+
apply: false
|
|
408
|
+
});
|
|
409
|
+
}
|
|
197
410
|
async scanCode(code, customerId) {
|
|
198
411
|
var _a, _b, _c, _d, _e;
|
|
199
412
|
const resultDiscountWithReason = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, { customerId })) || { discountList: [], unavailableReasonKey: null };
|
|
@@ -204,6 +417,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
204
417
|
type: "clientCalc",
|
|
205
418
|
isAvailable: false,
|
|
206
419
|
discountList: this.getDiscountList(),
|
|
420
|
+
scannedDiscountList: resultDiscountList,
|
|
207
421
|
unavailableReason: import_types2.UnavailableReason.Unknown
|
|
208
422
|
};
|
|
209
423
|
}
|
|
@@ -212,6 +426,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
212
426
|
type: "server",
|
|
213
427
|
isAvailable: false,
|
|
214
428
|
discountList: this.getDiscountList(),
|
|
429
|
+
scannedDiscountList: resultDiscountList,
|
|
215
430
|
unavailableReasonKey
|
|
216
431
|
};
|
|
217
432
|
}
|
|
@@ -224,7 +439,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
224
439
|
return {
|
|
225
440
|
type: "clientCalc",
|
|
226
441
|
isAvailable: true,
|
|
227
|
-
discountList: this.getDiscountList()
|
|
442
|
+
discountList: this.getDiscountList(),
|
|
443
|
+
scannedDiscountList: resultDiscountList
|
|
228
444
|
};
|
|
229
445
|
}
|
|
230
446
|
const tempOrder = this.store.tempOrder;
|
|
@@ -245,6 +461,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
245
461
|
type: "clientCalc",
|
|
246
462
|
isAvailable: isAvailable || false,
|
|
247
463
|
discountList: newDiscountList || this.getDiscountList(),
|
|
464
|
+
scannedDiscountList: resultDiscountList,
|
|
248
465
|
unavailableReason
|
|
249
466
|
};
|
|
250
467
|
}
|
|
@@ -253,6 +470,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
253
470
|
const tempOrder = this.store.tempOrder;
|
|
254
471
|
if (!tempOrder)
|
|
255
472
|
return;
|
|
473
|
+
delete tempOrder.discount_list;
|
|
256
474
|
const rulesModule = this.store.rules;
|
|
257
475
|
if (!rulesModule)
|
|
258
476
|
return;
|
|
@@ -266,7 +484,26 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
266
484
|
orderTotalAmount: Number(((_d = this.store.summary) == null ? void 0 : _d.total_amount) || 0)
|
|
267
485
|
});
|
|
268
486
|
if (result == null ? void 0 : result.productList) {
|
|
269
|
-
|
|
487
|
+
const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
|
|
488
|
+
tempOrder.products = this.applyProductDiscountPrices(
|
|
489
|
+
(result.productList || []).map((product, index) => {
|
|
490
|
+
const uid = (0, import_utils.getOrderProductLineUid)(product);
|
|
491
|
+
const previous = (uid ? previousProductsByUid.get(uid) : void 0) ?? previousProductsByUid.get(`__index__:${index}`);
|
|
492
|
+
if (isManualProductDiscountProduct(previous)) {
|
|
493
|
+
return previous;
|
|
494
|
+
}
|
|
495
|
+
const mergedProduct = previous ? (0, import_utils.mergeOrderProductDisplayFields)(previous, product) : product;
|
|
496
|
+
return {
|
|
497
|
+
...mergedProduct,
|
|
498
|
+
discount_list: (0, import_utils.normalizeOrderProductDiscountList)(
|
|
499
|
+
(0, import_manualProductDiscount.syncManualProductDiscountProductNum)(
|
|
500
|
+
mergedProduct.discount_list,
|
|
501
|
+
mergedProduct.num
|
|
502
|
+
)
|
|
503
|
+
)
|
|
504
|
+
};
|
|
505
|
+
})
|
|
506
|
+
);
|
|
270
507
|
}
|
|
271
508
|
if (result == null ? void 0 : result.discountList) {
|
|
272
509
|
OrderModule.populateSavedAmounts(
|
|
@@ -274,80 +511,201 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
274
511
|
result.discountList
|
|
275
512
|
);
|
|
276
513
|
(_e = this.store.discount) == null ? void 0 : _e.setDiscountList(result.discountList);
|
|
277
|
-
tempOrder.discount_list = result.discountList.filter(
|
|
278
|
-
(d) => d.isSelected
|
|
279
|
-
);
|
|
280
514
|
}
|
|
281
515
|
}
|
|
282
|
-
// ───
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
516
|
+
// ─── 促销/赠品 ──────────────────────────────────────
|
|
517
|
+
/**
|
|
518
|
+
* 注入促销评估器。
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* order.setPromotionEvaluator(appHelper.utils.promotionEvaluator);
|
|
522
|
+
*/
|
|
523
|
+
setPromotionEvaluator(evaluator) {
|
|
524
|
+
this.promotionEvaluator = evaluator || null;
|
|
289
525
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
526
|
+
/**
|
|
527
|
+
* 注入赠品选择 resolver。OS 需要补赠品时会 await 调用 resolver;缺省时跳过新增并 console.warn。
|
|
528
|
+
*
|
|
529
|
+
* @example
|
|
530
|
+
* order.setGiftSelectResolver(async (ctx) => {
|
|
531
|
+
* // SDK 内部决定弹窗 or 自动选第一项,返回完整 OrderProduct[]
|
|
532
|
+
* return giftSelectBridge.request(ctx);
|
|
533
|
+
* });
|
|
534
|
+
*/
|
|
535
|
+
setGiftSelectResolver(resolver) {
|
|
536
|
+
this.giftSelectResolver = resolver || null;
|
|
295
537
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
538
|
+
/**
|
|
539
|
+
* 为商品目录追加促销标签,供上层 Sales 门面复用。
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* const products = order.appendPromotionTags(catalogProducts);
|
|
543
|
+
*/
|
|
544
|
+
appendPromotionTags(products) {
|
|
545
|
+
return (0, import_cartPromotion.appendPromotionTags)(products, this.promotionEvaluator);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 应用购物车促销:计算 → 差异化赠品 → 写回 tempOrder.products → emit onPromotionApplied。
|
|
549
|
+
*
|
|
550
|
+
* 调用时机:写路径(add/update/remove/clear/setCustomer)末尾自动触发;外部一般无需手动调。
|
|
551
|
+
*
|
|
552
|
+
* 关键约束:
|
|
553
|
+
* - 不调用任何公开 CRUD API(如 removeProductFromOrder),全部内部 mutate tempOrder.products,避免事件风暴;
|
|
554
|
+
* - 用 `isApplyingPromotion` 防递归;
|
|
555
|
+
* - 多选项赠品依赖 giftSelectResolver,未注入则跳过且 console.warn;
|
|
556
|
+
* - 不主动调用 applyDiscount / recalculateSummary,调用方负责跟进。
|
|
557
|
+
*/
|
|
558
|
+
async applyPromotion() {
|
|
559
|
+
var _a;
|
|
560
|
+
if (this.isApplyingPromotion) {
|
|
300
561
|
return;
|
|
301
|
-
|
|
562
|
+
}
|
|
563
|
+
if (!this.promotionEvaluator) {
|
|
302
564
|
return;
|
|
303
|
-
|
|
304
|
-
|
|
565
|
+
}
|
|
566
|
+
const tempOrder = this.store.tempOrder;
|
|
567
|
+
if (!tempOrder) {
|
|
305
568
|
return;
|
|
569
|
+
}
|
|
570
|
+
this.isApplyingPromotion = true;
|
|
306
571
|
try {
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
this.
|
|
310
|
-
|
|
572
|
+
const result = (0, import_cartPromotion.processCartPromotion)(
|
|
573
|
+
tempOrder.products,
|
|
574
|
+
this.promotionEvaluator
|
|
575
|
+
);
|
|
576
|
+
if (result.giftActions.toRemove.length > 0) {
|
|
577
|
+
const removeSet = new Set(result.giftActions.toRemove.map(String));
|
|
578
|
+
result.products = result.products.filter((p) => {
|
|
579
|
+
const uid = (0, import_cartPromotion.getOrderProductUid)(p);
|
|
580
|
+
return uid ? !removeSet.has(String(uid)) : true;
|
|
581
|
+
});
|
|
311
582
|
}
|
|
312
|
-
|
|
313
|
-
for (
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
if (!Array.isArray(p.product_bundle)) {
|
|
321
|
-
p.product_bundle = [];
|
|
583
|
+
for (const reduce of result.giftActions.toReduce) {
|
|
584
|
+
for (const item of reduce.items) {
|
|
585
|
+
const product = result.products.find(
|
|
586
|
+
(p) => (0, import_cartPromotion.getOrderProductUid)(p) === item.uid
|
|
587
|
+
);
|
|
588
|
+
if (product) {
|
|
589
|
+
product.num = item.newQuantity;
|
|
322
590
|
}
|
|
323
|
-
const row = p;
|
|
324
|
-
parsedData.products[i] = (0, import_utils3.normalizeOrderProduct)(row);
|
|
325
591
|
}
|
|
326
592
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
593
|
+
if (result.giftActions.toAdd.length > 0) {
|
|
594
|
+
if (!this.giftSelectResolver) {
|
|
595
|
+
if (result.giftActions.toAdd.some((g) => g.giftOptions.length > 1)) {
|
|
596
|
+
console.warn(
|
|
597
|
+
"[OrderModule] giftSelectResolver not set, skip applying gifts",
|
|
598
|
+
result.giftActions.toAdd
|
|
599
|
+
);
|
|
600
|
+
} else {
|
|
601
|
+
console.warn(
|
|
602
|
+
"[OrderModule] giftSelectResolver not set, skip applying single-option gifts",
|
|
603
|
+
result.giftActions.toAdd
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
for (const addAction of result.giftActions.toAdd) {
|
|
608
|
+
if (addAction.giftOptions.length === 1) {
|
|
609
|
+
const sameStrategy = result.products.find(
|
|
610
|
+
(p) => {
|
|
611
|
+
var _a2, _b;
|
|
612
|
+
return ((_b = (_a2 = p.metadata) == null ? void 0 : _a2._giftInfo) == null ? void 0 : _b.strategyId) === addAction.strategyId;
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
if (sameStrategy && !sameStrategy.booking_uid && !((_a = sameStrategy.metadata) == null ? void 0 : _a.booking_uid)) {
|
|
616
|
+
sameStrategy.num = (Number(sameStrategy.num) || 0) + (addAction.giftCount || 1);
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
const giftResult = await this.giftSelectResolver({
|
|
622
|
+
strategyId: addAction.strategyId,
|
|
623
|
+
strategyName: addAction.strategyName,
|
|
624
|
+
giftCount: addAction.giftCount,
|
|
625
|
+
giftOptions: addAction.giftOptions,
|
|
626
|
+
sourceProductIds: addAction.sourceProductIds
|
|
627
|
+
});
|
|
628
|
+
const giftProducts = Array.isArray(giftResult) ? giftResult : giftResult == null ? void 0 : giftResult.products;
|
|
629
|
+
const giftBookings = Array.isArray(giftResult) ? [] : (giftResult == null ? void 0 : giftResult.bookings) || [];
|
|
630
|
+
if (Array.isArray(giftProducts) && giftProducts.length > 0) {
|
|
631
|
+
for (const [index, gp] of giftProducts.entries()) {
|
|
632
|
+
if (!gp)
|
|
633
|
+
continue;
|
|
634
|
+
const booking = giftBookings[index];
|
|
635
|
+
if (booking) {
|
|
636
|
+
const linked = this.createLinkedProductAndBooking({
|
|
637
|
+
product: gp,
|
|
638
|
+
booking
|
|
639
|
+
});
|
|
640
|
+
result.products.push(linked.product);
|
|
641
|
+
tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
result.products.push(gp);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
} catch (error) {
|
|
648
|
+
console.warn(
|
|
649
|
+
"[OrderModule] giftSelectResolver rejected, skip add gift",
|
|
650
|
+
addAction.strategyId,
|
|
651
|
+
error
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
338
656
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
657
|
+
tempOrder.products = result.products;
|
|
658
|
+
this.lastUnfulfilledPromotions = result.unfulfilledPromotions;
|
|
659
|
+
this.lastGiftActions = result.giftActions;
|
|
660
|
+
const payload = {
|
|
661
|
+
unfulfilledPromotions: result.unfulfilledPromotions,
|
|
662
|
+
giftActions: result.giftActions,
|
|
663
|
+
gifts: result.gifts.map((g) => ({
|
|
664
|
+
strategyId: g.strategyId,
|
|
665
|
+
strategyName: g.strategyName,
|
|
666
|
+
giftCount: g.giftCount,
|
|
667
|
+
giftOptions: g.giftOptions
|
|
668
|
+
})),
|
|
669
|
+
products: tempOrder.products
|
|
670
|
+
};
|
|
671
|
+
this.effectsEmit("onPromotionApplied", payload);
|
|
672
|
+
} catch (error) {
|
|
673
|
+
console.error("[OrderModule] applyPromotion failed", error);
|
|
674
|
+
} finally {
|
|
675
|
+
this.isApplyingPromotion = false;
|
|
342
676
|
}
|
|
343
677
|
}
|
|
678
|
+
/** 最近一次 applyPromotion 输出的未满足促销列表 */
|
|
679
|
+
getUnfulfilledPromotions() {
|
|
680
|
+
return this.lastUnfulfilledPromotions;
|
|
681
|
+
}
|
|
682
|
+
/** 最近一次 applyPromotion 输出的赠品操作 diff */
|
|
683
|
+
getLastGiftActions() {
|
|
684
|
+
return this.lastGiftActions;
|
|
685
|
+
}
|
|
686
|
+
// ─── TempOrder: 初始化入口 ───
|
|
687
|
+
initTempOrder(params) {
|
|
688
|
+
if (params.cacheId !== void 0)
|
|
689
|
+
this.cacheId = params.cacheId;
|
|
690
|
+
if (params.salesSummaryModuleName !== void 0)
|
|
691
|
+
this.salesSummaryModuleName = params.salesSummaryModuleName;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* 控制 IndexedDB 草稿(saveDraft)是否写入。
|
|
695
|
+
* localStorage 版 tempOrder 持久化已废弃,此方法仅影响 saveDraft。
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
|
|
699
|
+
*/
|
|
700
|
+
setEnableTempOrderPersist(enabled) {
|
|
701
|
+
this.draftPersistEnabled = enabled;
|
|
702
|
+
}
|
|
703
|
+
/** 是否允许 saveDraft 写入 IndexedDB 草稿。 */
|
|
704
|
+
isTempOrderPersistEnabled() {
|
|
705
|
+
return this.draftPersistEnabled;
|
|
706
|
+
}
|
|
707
|
+
/** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化;草稿保存请使用 IndexedDB saveDraft。 */
|
|
344
708
|
persistTempOrder() {
|
|
345
|
-
const key = this.getTempOrderStorageKey();
|
|
346
|
-
if (!key || !this.store.tempOrder)
|
|
347
|
-
return;
|
|
348
|
-
if (!this.window)
|
|
349
|
-
return;
|
|
350
|
-
this.window.localStorage.setItem(key, JSON.stringify(this.store.tempOrder));
|
|
351
709
|
}
|
|
352
710
|
// ─── TempOrder: 创建 & 获取 ───
|
|
353
711
|
createDefaultTempOrderInstance() {
|
|
@@ -391,107 +749,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
391
749
|
}
|
|
392
750
|
return tempOrder.request_unique_idempotency_token;
|
|
393
751
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
id: tempOrder.order_id ?? externalSaleNumber,
|
|
402
|
-
external_sale_number: externalSaleNumber,
|
|
403
|
-
summary: this.store.summary || (0, import_utils.createEmptySummary)(),
|
|
404
|
-
lastOrderInfo: this.store.lastOrderInfo
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
async getLocalOrderByOrderId(orderId) {
|
|
408
|
-
var _a, _b, _c, _d;
|
|
409
|
-
if (!this.dbManager || orderId === void 0 || orderId === null)
|
|
410
|
-
return null;
|
|
411
|
-
try {
|
|
412
|
-
const direct = await ((_b = (_a = this.dbManager).get) == null ? void 0 : _b.call(
|
|
413
|
-
_a,
|
|
414
|
-
LOCAL_ORDER_STORE_NAME,
|
|
415
|
-
orderId
|
|
416
|
-
));
|
|
417
|
-
if (direct)
|
|
418
|
-
return direct;
|
|
419
|
-
const orders = await ((_d = (_c = this.dbManager).getAll) == null ? void 0 : _d.call(_c, LOCAL_ORDER_STORE_NAME));
|
|
420
|
-
return (orders || []).find(
|
|
421
|
-
(order) => String(order == null ? void 0 : order.order_id) === String(orderId)
|
|
422
|
-
) || null;
|
|
423
|
-
} catch (error) {
|
|
424
|
-
this.logWarning("getLocalOrderByOrderId failed", {
|
|
425
|
-
orderId,
|
|
426
|
-
error: error instanceof Error ? error.message : String(error)
|
|
427
|
-
});
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
async getLocalOrderByOrderNumber(orderNumber) {
|
|
432
|
-
var _a, _b, _c, _d;
|
|
433
|
-
if (!this.dbManager || !orderNumber)
|
|
434
|
-
return null;
|
|
435
|
-
try {
|
|
436
|
-
const direct = await ((_b = (_a = this.dbManager).get) == null ? void 0 : _b.call(
|
|
437
|
-
_a,
|
|
438
|
-
LOCAL_ORDER_STORE_NAME,
|
|
439
|
-
orderNumber
|
|
440
|
-
));
|
|
441
|
-
if (direct)
|
|
442
|
-
return direct;
|
|
443
|
-
const orders = await ((_d = (_c = this.dbManager).getAll) == null ? void 0 : _d.call(_c, LOCAL_ORDER_STORE_NAME));
|
|
444
|
-
return (orders || []).find(
|
|
445
|
-
(order) => String(order == null ? void 0 : order.order_number) === String(orderNumber)
|
|
446
|
-
) || null;
|
|
447
|
-
} catch (error) {
|
|
448
|
-
this.logWarning("getLocalOrderByOrderNumber failed", {
|
|
449
|
-
orderNumber,
|
|
450
|
-
error: error instanceof Error ? error.message : String(error)
|
|
451
|
-
});
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
async getLocalOrderByExternalSaleNumber(externalSaleNumber) {
|
|
456
|
-
var _a, _b, _c, _d;
|
|
457
|
-
if (!this.dbManager || !externalSaleNumber)
|
|
458
|
-
return null;
|
|
459
|
-
try {
|
|
460
|
-
const direct = await ((_b = (_a = this.dbManager).get) == null ? void 0 : _b.call(
|
|
461
|
-
_a,
|
|
462
|
-
LOCAL_ORDER_STORE_NAME,
|
|
463
|
-
externalSaleNumber
|
|
464
|
-
));
|
|
465
|
-
if (direct)
|
|
466
|
-
return direct;
|
|
467
|
-
const orders = await ((_d = (_c = this.dbManager).getAll) == null ? void 0 : _d.call(_c, LOCAL_ORDER_STORE_NAME));
|
|
468
|
-
return (orders || []).find(
|
|
469
|
-
(order) => String(order == null ? void 0 : order.external_sale_number) === String(externalSaleNumber)
|
|
470
|
-
) || null;
|
|
471
|
-
} catch (error) {
|
|
472
|
-
this.logWarning("getLocalOrderByExternalSaleNumber failed", {
|
|
473
|
-
externalSaleNumber,
|
|
474
|
-
error: error instanceof Error ? error.message : String(error)
|
|
475
|
-
});
|
|
476
|
-
return null;
|
|
477
|
-
}
|
|
752
|
+
buildPaymentSyncIdempotencyToken(tempOrder, payments) {
|
|
753
|
+
const baseToken = this.ensureRequestUniqueIdempotencyToken(tempOrder);
|
|
754
|
+
const paidPaymentsCount = (payments || []).filter((payment) => {
|
|
755
|
+
return String((payment == null ? void 0 : payment.status) || "").toLowerCase() === "paid";
|
|
756
|
+
}).length;
|
|
757
|
+
const paidCount = paidPaymentsCount > 0 ? paidPaymentsCount : payments.length;
|
|
758
|
+
return `${baseToken}_payment_${paidCount}`;
|
|
478
759
|
}
|
|
479
760
|
async saveDraft() {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
const tempOrder = this.ensureTempOrder();
|
|
484
|
-
const record = this.buildLocalOrderRecord(tempOrder);
|
|
485
|
-
try {
|
|
486
|
-
await ((_b = (_a = this.dbManager).update) == null ? void 0 : _b.call(_a, LOCAL_ORDER_STORE_NAME, record));
|
|
487
|
-
} catch (error) {
|
|
488
|
-
this.logWarning("saveDraft failed", {
|
|
489
|
-
externalSaleNumber: tempOrder.external_sale_number,
|
|
490
|
-
orderNumber: tempOrder.order_number,
|
|
491
|
-
orderId: tempOrder.order_id,
|
|
492
|
-
error: error instanceof Error ? error.message : String(error)
|
|
493
|
-
});
|
|
494
|
-
}
|
|
761
|
+
}
|
|
762
|
+
saveDraftInBackground() {
|
|
763
|
+
void this.saveDraft();
|
|
495
764
|
}
|
|
496
765
|
async hydrateTempOrderFromLocalRecord(record) {
|
|
497
766
|
return this.hydrateTempOrderFromRecord(record);
|
|
@@ -500,15 +769,208 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
500
769
|
var _a, _b;
|
|
501
770
|
return ((_a = result == null ? void 0 : result.data) == null ? void 0 : _a.order_id) ?? (result == null ? void 0 : result.order_id) ?? ((_b = result == null ? void 0 : result.data) == null ? void 0 : _b.id) ?? (result == null ? void 0 : result.id) ?? null;
|
|
502
771
|
}
|
|
772
|
+
calculatePaymentEffectiveAmount(payment) {
|
|
773
|
+
const amount = new import_decimal.default(payment.amount || 0).minus(new import_decimal.default(payment.service_fee || 0));
|
|
774
|
+
const rounding = new import_decimal.default(payment.rounding_amount || 0);
|
|
775
|
+
return amount.minus(rounding);
|
|
776
|
+
}
|
|
503
777
|
calculatePaymentTotal(payments) {
|
|
504
778
|
return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
|
|
505
779
|
includeVoided: false
|
|
506
780
|
}).reduce((sum, payment) => {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
781
|
+
return sum.plus(this.calculatePaymentEffectiveAmount(payment));
|
|
782
|
+
}, new import_decimal.default(0));
|
|
783
|
+
}
|
|
784
|
+
getDepositAmount(tempOrder, summary) {
|
|
785
|
+
return new import_decimal.default(summary.deposit_amount || tempOrder.deposit_amount || "0.00");
|
|
786
|
+
}
|
|
787
|
+
normalizeDepositAmount(amount) {
|
|
788
|
+
return import_decimal.default.max(new import_decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
|
|
789
|
+
}
|
|
790
|
+
applyDepositAmountToSummary(tempOrder, summary, amount) {
|
|
791
|
+
const depositAmount = this.normalizeDepositAmount(amount);
|
|
792
|
+
const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
|
|
793
|
+
const existedDeposit = summary.deposit && typeof summary.deposit === "object" ? summary.deposit : void 0;
|
|
794
|
+
const nextSummary = {
|
|
795
|
+
...summary,
|
|
796
|
+
deposit_amount: depositAmount,
|
|
797
|
+
deposit: hasDepositAmount ? {
|
|
798
|
+
...existedDeposit || {},
|
|
799
|
+
total: depositAmount,
|
|
800
|
+
deposit_policy_ids: (existedDeposit == null ? void 0 : existedDeposit.deposit_policy_ids) || [],
|
|
801
|
+
hasDeposit: true
|
|
802
|
+
} : void 0
|
|
803
|
+
};
|
|
804
|
+
tempOrder.deposit_amount = depositAmount;
|
|
805
|
+
tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
|
|
806
|
+
return nextSummary;
|
|
807
|
+
}
|
|
808
|
+
isDepositOrder(tempOrder, depositAmount) {
|
|
809
|
+
return tempOrder.is_deposit === 1 || depositAmount.gt(0);
|
|
810
|
+
}
|
|
811
|
+
getOrderExpectedAmount(summary) {
|
|
812
|
+
return new import_decimal.default(summary.expect_amount || summary.total_amount || 0);
|
|
813
|
+
}
|
|
814
|
+
isDepositCovered(params) {
|
|
815
|
+
const depositAmount = this.getDepositAmount(params.tempOrder, params.summary);
|
|
816
|
+
if (!this.isDepositOrder(params.tempOrder, depositAmount))
|
|
817
|
+
return false;
|
|
818
|
+
if (depositAmount.lte(0))
|
|
819
|
+
return false;
|
|
820
|
+
return params.paidAmount.gte(depositAmount);
|
|
821
|
+
}
|
|
822
|
+
calculateDepositPaidAmount(payments) {
|
|
823
|
+
return (payments || []).reduce((sum, payment) => {
|
|
824
|
+
const paymentRecord = payment;
|
|
825
|
+
if ((paymentRecord == null ? void 0 : paymentRecord.status) !== "paid")
|
|
826
|
+
return sum;
|
|
827
|
+
const isDepositPayment = paymentRecord.type === "deposit" || paymentRecord.order_payment_type === "deposit";
|
|
828
|
+
if (!isDepositPayment)
|
|
829
|
+
return sum;
|
|
830
|
+
if (paymentRecord.origin_amount !== void 0 && paymentRecord.origin_amount !== null && paymentRecord.origin_amount !== "") {
|
|
831
|
+
return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
|
|
832
|
+
}
|
|
833
|
+
const rounding = new import_decimal.default(paymentRecord.rounding_amount || 0);
|
|
834
|
+
return sum.plus(new import_decimal.default(paymentRecord.amount || 0).minus(rounding));
|
|
510
835
|
}, new import_decimal.default(0));
|
|
511
836
|
}
|
|
837
|
+
resolveNextOrderPaymentType(tempOrder) {
|
|
838
|
+
const depositAmount = new import_decimal.default(tempOrder.deposit_amount || "0.00");
|
|
839
|
+
if (!this.isDepositOrder(tempOrder, depositAmount))
|
|
840
|
+
return "normal";
|
|
841
|
+
if (depositAmount.lte(0))
|
|
842
|
+
return "normal";
|
|
843
|
+
const depositPaidAmount = this.calculateDepositPaidAmount(tempOrder.payments || []);
|
|
844
|
+
return depositPaidAmount.lt(depositAmount) ? "deposit" : "normal";
|
|
845
|
+
}
|
|
846
|
+
normalizePaymentSource(payment, options) {
|
|
847
|
+
const paymentRecord = payment;
|
|
848
|
+
const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
|
|
849
|
+
if (!metadata.unique_payment_number) {
|
|
850
|
+
metadata.unique_payment_number = (0, import_utils.createUuidV4)();
|
|
851
|
+
}
|
|
852
|
+
const normalized = {
|
|
853
|
+
...paymentRecord,
|
|
854
|
+
metadata,
|
|
855
|
+
origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
|
|
856
|
+
};
|
|
857
|
+
if (paymentRecord.status !== void 0) {
|
|
858
|
+
normalized.status = paymentRecord.status;
|
|
859
|
+
} else if ((options == null ? void 0 : options.defaultPaid) !== false) {
|
|
860
|
+
normalized.status = "paid";
|
|
861
|
+
}
|
|
862
|
+
return normalized;
|
|
863
|
+
}
|
|
864
|
+
updateTempOrderPaymentStatus(tempOrder, options) {
|
|
865
|
+
const summary = (options == null ? void 0 : options.summary) || this.store.summary || (0, import_utils.createEmptySummary)();
|
|
866
|
+
const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
|
|
867
|
+
const refundAmount = this.getSummaryRefundAmount(summary);
|
|
868
|
+
const netPaymentTotal = import_decimal.default.max(paymentTotal.minus(refundAmount), 0);
|
|
869
|
+
const targetAmount = this.calculatePaymentTargetAmount(
|
|
870
|
+
tempOrder,
|
|
871
|
+
summary,
|
|
872
|
+
netPaymentTotal
|
|
873
|
+
);
|
|
874
|
+
if (this.shouldKeepPaymentStatusAfterAmountRecalc(tempOrder.payment_status, {
|
|
875
|
+
netPaymentTotal,
|
|
876
|
+
paymentTotal,
|
|
877
|
+
refundAmount,
|
|
878
|
+
targetAmount,
|
|
879
|
+
previousSummary: options == null ? void 0 : options.previousSummary,
|
|
880
|
+
tempOrder
|
|
881
|
+
})) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
if (targetAmount.lte(0)) {
|
|
885
|
+
tempOrder.payment_status = "paid";
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
if (netPaymentTotal.lte(0)) {
|
|
889
|
+
tempOrder.payment_status = "payment_processing";
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
tempOrder.payment_status = netPaymentTotal.gte(targetAmount) ? "paid" : "partially_paid";
|
|
893
|
+
}
|
|
894
|
+
shouldKeepPaymentStatusAfterAmountRecalc(paymentStatus, params) {
|
|
895
|
+
const normalizedStatus = String(paymentStatus || "").trim().toLowerCase();
|
|
896
|
+
if (normalizedStatus !== "refunded" && normalizedStatus !== "partially_refunded") {
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
if (params.refundAmount.lte(0))
|
|
900
|
+
return false;
|
|
901
|
+
if (params.previousSummary) {
|
|
902
|
+
const previousTargetAmount = this.calculatePaymentTargetAmount(
|
|
903
|
+
params.tempOrder,
|
|
904
|
+
params.previousSummary,
|
|
905
|
+
params.netPaymentTotal
|
|
906
|
+
);
|
|
907
|
+
if (!previousTargetAmount.eq(params.targetAmount))
|
|
908
|
+
return false;
|
|
909
|
+
}
|
|
910
|
+
if (normalizedStatus === "refunded") {
|
|
911
|
+
return params.refundAmount.gte(params.paymentTotal);
|
|
912
|
+
}
|
|
913
|
+
return params.netPaymentTotal.gte(params.targetAmount);
|
|
914
|
+
}
|
|
915
|
+
resolveWalletPassUseValue(payment, amount) {
|
|
916
|
+
const usageUnit = payment.wallet_pass_usage_unit && typeof payment.wallet_pass_usage_unit === "object" ? payment.wallet_pass_usage_unit : null;
|
|
917
|
+
if (!usageUnit)
|
|
918
|
+
return payment.wallet_pass_use_value;
|
|
919
|
+
const price = new import_decimal.default(usageUnit.price || 0);
|
|
920
|
+
const points = new import_decimal.default(usageUnit.points || 0);
|
|
921
|
+
if (price.lte(0) || points.lte(0))
|
|
922
|
+
return payment.wallet_pass_use_value;
|
|
923
|
+
return amount.div(price).times(points).toDecimalPlaces(2).toFixed(2);
|
|
924
|
+
}
|
|
925
|
+
adjustVoucherFundRecord(params) {
|
|
926
|
+
var _a;
|
|
927
|
+
const fundRecord = params.voucher.fund_record && typeof params.voucher.fund_record === "object" && !Array.isArray(params.voucher.fund_record) ? { ...params.voucher.fund_record } : null;
|
|
928
|
+
if (!fundRecord || fundRecord.using_before_value === void 0 || fundRecord.using_before_value === null) {
|
|
929
|
+
return fundRecord || void 0;
|
|
930
|
+
}
|
|
931
|
+
const code = String(params.voucher.code || "").toUpperCase();
|
|
932
|
+
const isPointCard = code === "POINTCARD" || String(((_a = params.voucher.fund_record) == null ? void 0 : _a.tag) || "").toLowerCase() === "point_card";
|
|
933
|
+
const usingValue = isPointCard ? new import_decimal.default(params.walletPassUseValue || 0) : params.amount;
|
|
934
|
+
fundRecord.using_after_value = new import_decimal.default(fundRecord.using_before_value || 0).minus(usingValue).toDecimalPlaces(2).toFixed(2);
|
|
935
|
+
return fundRecord;
|
|
936
|
+
}
|
|
937
|
+
capVoucherPaymentsByRemainingAmount(params) {
|
|
938
|
+
const targetAmount = this.getPaymentTargetAmount();
|
|
939
|
+
const nonVoucherTotal = this.calculatePaymentTotal(params.nonVoucherPayments);
|
|
940
|
+
if (targetAmount.lte(0))
|
|
941
|
+
return [];
|
|
942
|
+
let remainingAmount = import_decimal.default.max(
|
|
943
|
+
targetAmount.minus(nonVoucherTotal),
|
|
944
|
+
0
|
|
945
|
+
);
|
|
946
|
+
const cappedVouchers = [];
|
|
947
|
+
for (const voucher of params.vouchers) {
|
|
948
|
+
if (remainingAmount.lte(0))
|
|
949
|
+
break;
|
|
950
|
+
const voucherAmount = import_decimal.default.max(new import_decimal.default(voucher.amount || 0), 0);
|
|
951
|
+
if (voucherAmount.lte(0))
|
|
952
|
+
continue;
|
|
953
|
+
const cappedAmount = import_decimal.default.min(voucherAmount, remainingAmount);
|
|
954
|
+
const amountText = cappedAmount.toDecimalPlaces(2).toFixed(2);
|
|
955
|
+
const walletPassUseValue = this.resolveWalletPassUseValue(
|
|
956
|
+
voucher,
|
|
957
|
+
cappedAmount
|
|
958
|
+
);
|
|
959
|
+
cappedVouchers.push({
|
|
960
|
+
...voucher,
|
|
961
|
+
amount: amountText,
|
|
962
|
+
origin_amount: amountText,
|
|
963
|
+
wallet_pass_use_value: walletPassUseValue,
|
|
964
|
+
fund_record: this.adjustVoucherFundRecord({
|
|
965
|
+
voucher,
|
|
966
|
+
amount: cappedAmount,
|
|
967
|
+
walletPassUseValue
|
|
968
|
+
})
|
|
969
|
+
});
|
|
970
|
+
remainingAmount = remainingAmount.minus(cappedAmount);
|
|
971
|
+
}
|
|
972
|
+
return cappedVouchers;
|
|
973
|
+
}
|
|
512
974
|
calculatePaidPaymentSummary(payments) {
|
|
513
975
|
return (payments || []).reduce(
|
|
514
976
|
(summary, payment) => {
|
|
@@ -518,13 +980,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
518
980
|
return {
|
|
519
981
|
customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
|
|
520
982
|
orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
|
|
521
|
-
|
|
983
|
+
gapPaidAmount: summary.gapPaidAmount.plus(this.calculatePaymentGapAmount(paymentRecord)),
|
|
984
|
+
payServiceChargeAmount: summary.payServiceChargeAmount.plus(this.calculatePaymentServiceFee(paymentRecord)),
|
|
985
|
+
roundingAmount: summary.roundingAmount.plus(this.calculatePaymentRoundingAmount(paymentRecord))
|
|
522
986
|
};
|
|
523
987
|
},
|
|
524
988
|
{
|
|
525
989
|
customerPaidAmount: new import_decimal.default(0),
|
|
526
990
|
orderPaidAmount: new import_decimal.default(0),
|
|
527
|
-
|
|
991
|
+
gapPaidAmount: new import_decimal.default(0),
|
|
992
|
+
payServiceChargeAmount: new import_decimal.default(0),
|
|
993
|
+
roundingAmount: new import_decimal.default(0)
|
|
528
994
|
}
|
|
529
995
|
);
|
|
530
996
|
}
|
|
@@ -537,15 +1003,363 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
537
1003
|
const fixedAmount = new import_decimal.default(serviceCharge.amount || 0);
|
|
538
1004
|
return new import_decimal.default(payment.amount || 0).times(percentage).plus(fixedAmount);
|
|
539
1005
|
}
|
|
1006
|
+
calculatePaymentGapAmount(payment) {
|
|
1007
|
+
if (payment.origin_amount === void 0 || payment.origin_amount === null || payment.origin_amount === "") {
|
|
1008
|
+
return new import_decimal.default(0);
|
|
1009
|
+
}
|
|
1010
|
+
const rounding = new import_decimal.default(payment.rounding_amount || 0);
|
|
1011
|
+
return new import_decimal.default(payment.origin_amount || 0).minus(rounding);
|
|
1012
|
+
}
|
|
1013
|
+
calculatePaymentRoundingAmount(payment) {
|
|
1014
|
+
if (payment.rounding_amount === void 0 || payment.rounding_amount === null || payment.rounding_amount === "") {
|
|
1015
|
+
return new import_decimal.default(0);
|
|
1016
|
+
}
|
|
1017
|
+
return new import_decimal.default(payment.rounding_amount || 0);
|
|
1018
|
+
}
|
|
1019
|
+
formatSummaryMetadataMoney(value) {
|
|
1020
|
+
if (value === void 0 || value === null || value === "")
|
|
1021
|
+
return void 0;
|
|
1022
|
+
if (value instanceof import_decimal.default)
|
|
1023
|
+
return value.toFixed(2);
|
|
1024
|
+
return new import_decimal.default(String(value || 0)).toFixed(2);
|
|
1025
|
+
}
|
|
1026
|
+
syncSummaryProductMetadata(products) {
|
|
1027
|
+
const moneyKeys = [
|
|
1028
|
+
"main_product_attached_bundle_surcharge_fee",
|
|
1029
|
+
"main_product_attached_bundle_tax_fee",
|
|
1030
|
+
"surcharge_rounding_remainder",
|
|
1031
|
+
"tax_fee_rounding_remainder"
|
|
1032
|
+
];
|
|
1033
|
+
const metadataMoneyKeys = [
|
|
1034
|
+
"main_product_attached_bundle_selling_price",
|
|
1035
|
+
"main_product_attached_bundle_payment_price"
|
|
1036
|
+
];
|
|
1037
|
+
for (const product of products || []) {
|
|
1038
|
+
const productRecord = product;
|
|
1039
|
+
const metadata = productRecord.metadata && typeof productRecord.metadata === "object" ? { ...productRecord.metadata } : {};
|
|
1040
|
+
let hasMetadataPatch = false;
|
|
1041
|
+
for (const key of moneyKeys) {
|
|
1042
|
+
const value = this.formatSummaryMetadataMoney(productRecord[key]);
|
|
1043
|
+
if (value === void 0)
|
|
1044
|
+
continue;
|
|
1045
|
+
metadata[key] = value;
|
|
1046
|
+
hasMetadataPatch = true;
|
|
1047
|
+
}
|
|
1048
|
+
for (const key of metadataMoneyKeys) {
|
|
1049
|
+
const value = this.formatSummaryMetadataMoney(metadata[key]);
|
|
1050
|
+
if (value === void 0)
|
|
1051
|
+
continue;
|
|
1052
|
+
metadata[key] = value;
|
|
1053
|
+
hasMetadataPatch = true;
|
|
1054
|
+
}
|
|
1055
|
+
if (metadata.average_discount_amount_rate !== void 0) {
|
|
1056
|
+
hasMetadataPatch = true;
|
|
1057
|
+
}
|
|
1058
|
+
if (Array.isArray(productRecord.relation_surcharge_ids)) {
|
|
1059
|
+
metadata.relation_surcharge_ids = productRecord.relation_surcharge_ids;
|
|
1060
|
+
hasMetadataPatch = true;
|
|
1061
|
+
}
|
|
1062
|
+
const productPaymentPrice = this.formatSummaryMetadataMoney(
|
|
1063
|
+
productRecord.payment_price
|
|
1064
|
+
);
|
|
1065
|
+
if (productPaymentPrice !== void 0) {
|
|
1066
|
+
productRecord.payment_price = productPaymentPrice;
|
|
1067
|
+
}
|
|
1068
|
+
if (hasMetadataPatch)
|
|
1069
|
+
productRecord.metadata = metadata;
|
|
1070
|
+
if (!Array.isArray(productRecord.product_bundle))
|
|
1071
|
+
continue;
|
|
1072
|
+
for (const bundle of productRecord.product_bundle) {
|
|
1073
|
+
const bundleRecord = bundle;
|
|
1074
|
+
const bundleMetadata = bundleRecord.metadata && typeof bundleRecord.metadata === "object" ? { ...bundleRecord.metadata } : {};
|
|
1075
|
+
let hasBundleMetadataPatch = false;
|
|
1076
|
+
const bundleSurchargeFee = this.formatSummaryMetadataMoney(
|
|
1077
|
+
bundleRecord.surcharge_fee
|
|
1078
|
+
);
|
|
1079
|
+
if (bundleSurchargeFee !== void 0) {
|
|
1080
|
+
bundleMetadata.surcharge_fee = bundleSurchargeFee;
|
|
1081
|
+
hasBundleMetadataPatch = true;
|
|
1082
|
+
}
|
|
1083
|
+
const bundlePaymentPrice = this.formatSummaryMetadataMoney(
|
|
1084
|
+
bundleRecord.bundle_payment_price
|
|
1085
|
+
);
|
|
1086
|
+
if (bundlePaymentPrice !== void 0) {
|
|
1087
|
+
bundleRecord.bundle_payment_price = bundlePaymentPrice;
|
|
1088
|
+
}
|
|
1089
|
+
if (Array.isArray(bundleRecord.relation_surcharge_ids)) {
|
|
1090
|
+
bundleMetadata.relation_surcharge_ids = bundleRecord.relation_surcharge_ids;
|
|
1091
|
+
hasBundleMetadataPatch = true;
|
|
1092
|
+
}
|
|
1093
|
+
if (hasBundleMetadataPatch)
|
|
1094
|
+
bundleRecord.metadata = bundleMetadata;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
calculateSummaryAmountGap(params) {
|
|
1099
|
+
const { tempOrder, summary, orderPaidAmount } = params;
|
|
1100
|
+
const refundAmount = this.getSummaryRefundAmount(summary);
|
|
1101
|
+
const netOrderPaidAmount = import_decimal.default.max(orderPaidAmount.minus(refundAmount), 0);
|
|
1102
|
+
const targetAmount = this.calculatePaymentTargetAmount(
|
|
1103
|
+
tempOrder,
|
|
1104
|
+
summary,
|
|
1105
|
+
netOrderPaidAmount
|
|
1106
|
+
);
|
|
1107
|
+
return targetAmount.minus(netOrderPaidAmount).toFixed(2);
|
|
1108
|
+
}
|
|
1109
|
+
getSummaryRefundAmount(summary) {
|
|
1110
|
+
return import_decimal.default.max(new import_decimal.default((summary == null ? void 0 : summary.total_refund_amount) || 0), 0);
|
|
1111
|
+
}
|
|
1112
|
+
calculatePaymentTargetAmount(tempOrder, summary, paidAmount = new import_decimal.default(0)) {
|
|
1113
|
+
const depositAmount = this.getDepositAmount(tempOrder, summary);
|
|
1114
|
+
if (!this.isDepositOrder(tempOrder, depositAmount)) {
|
|
1115
|
+
return this.getOrderExpectedAmount(summary);
|
|
1116
|
+
}
|
|
1117
|
+
if (this.isDepositCovered({ tempOrder, summary, paidAmount })) {
|
|
1118
|
+
return this.getOrderExpectedAmount(summary);
|
|
1119
|
+
}
|
|
1120
|
+
return depositAmount;
|
|
1121
|
+
}
|
|
1122
|
+
normalizeFingerprintMoney(value) {
|
|
1123
|
+
if (value === void 0 || value === null || value === "")
|
|
1124
|
+
return "";
|
|
1125
|
+
try {
|
|
1126
|
+
const parsed = new import_decimal.default(String(value || 0));
|
|
1127
|
+
return parsed.toFixed(4);
|
|
1128
|
+
} catch {
|
|
1129
|
+
return String(value);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
normalizeFingerprintValue(value) {
|
|
1133
|
+
if (Array.isArray(value)) {
|
|
1134
|
+
return value.map((item) => this.normalizeFingerprintValue(item));
|
|
1135
|
+
}
|
|
1136
|
+
if (!value || typeof value !== "object")
|
|
1137
|
+
return value ?? "";
|
|
1138
|
+
return Object.keys(value).sort().reduce((result, key) => {
|
|
1139
|
+
result[key] = this.normalizeFingerprintValue(value[key]);
|
|
1140
|
+
return result;
|
|
1141
|
+
}, {});
|
|
1142
|
+
}
|
|
1143
|
+
buildProductFingerprintItem(product) {
|
|
1144
|
+
const sku = (product == null ? void 0 : product.product_sku) || {};
|
|
1145
|
+
const metadata = (product == null ? void 0 : product.metadata) || {};
|
|
1146
|
+
const discountTypes = ((product == null ? void 0 : product.discount_list) || []).map((discount) => (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag));
|
|
1147
|
+
const extensionType = (product == null ? void 0 : product.extension_type) || (discountTypes.includes("good_pass") ? "good_pass" : "normal");
|
|
1148
|
+
return {
|
|
1149
|
+
product_id: (product == null ? void 0 : product.product_id) ?? null,
|
|
1150
|
+
product_variant_id: (product == null ? void 0 : product.product_variant_id) ?? null,
|
|
1151
|
+
extension_type: extensionType,
|
|
1152
|
+
num: (0, import_utils3.getSafeProductNum)((product == null ? void 0 : product.num) ?? (product == null ? void 0 : product.product_quantity)),
|
|
1153
|
+
selling_price: this.normalizeFingerprintMoney(product == null ? void 0 : product.selling_price),
|
|
1154
|
+
original_price: this.normalizeFingerprintMoney(product == null ? void 0 : product.original_price),
|
|
1155
|
+
payment_price: this.normalizeFingerprintMoney((product == null ? void 0 : product.payment_price) ?? (product == null ? void 0 : product.selling_price)),
|
|
1156
|
+
metadata: {
|
|
1157
|
+
source_product_price: this.normalizeFingerprintMoney(metadata.source_product_price),
|
|
1158
|
+
main_product_selling_price: this.normalizeFingerprintMoney(metadata.main_product_selling_price),
|
|
1159
|
+
main_product_original_price: this.normalizeFingerprintMoney(metadata.main_product_original_price),
|
|
1160
|
+
product_discount_difference: this.normalizeFingerprintMoney(metadata.product_discount_difference)
|
|
1161
|
+
},
|
|
1162
|
+
product_sku: this.normalizeFingerprintValue({
|
|
1163
|
+
code: sku.code ?? "",
|
|
1164
|
+
barcode: sku.barcode ?? "",
|
|
1165
|
+
variant_id: sku.variant_id ?? (product == null ? void 0 : product.product_variant_id) ?? 0,
|
|
1166
|
+
variant: sku.variant || [],
|
|
1167
|
+
option: (0, import_utils.getProductSkuOptions)(product || {}).map((option) => ({
|
|
1168
|
+
id: (option == null ? void 0 : option.id) ?? (option == null ? void 0 : option.option_group_item_id) ?? null,
|
|
1169
|
+
option_group_id: (option == null ? void 0 : option.option_group_id) ?? null,
|
|
1170
|
+
option_group_item_id: (option == null ? void 0 : option.option_group_item_id) ?? (option == null ? void 0 : option.id) ?? null,
|
|
1171
|
+
num: Number((option == null ? void 0 : option.num) ?? 1) || 1,
|
|
1172
|
+
add_price: this.normalizeFingerprintMoney((option == null ? void 0 : option.add_price) ?? (option == null ? void 0 : option.price))
|
|
1173
|
+
}))
|
|
1174
|
+
}),
|
|
1175
|
+
product_bundle: this.normalizeFingerprintValue(((product == null ? void 0 : product.product_bundle) || []).map((bundle) => ({
|
|
1176
|
+
bundle_product_id: (bundle == null ? void 0 : bundle.bundle_product_id) ?? (bundle == null ? void 0 : bundle._bundle_product_id) ?? (bundle == null ? void 0 : bundle.product_id) ?? null,
|
|
1177
|
+
bundle_variant_id: (bundle == null ? void 0 : bundle.bundle_variant_id) ?? (bundle == null ? void 0 : bundle.product_variant_id) ?? 0,
|
|
1178
|
+
num: (0, import_utils3.getSafeProductNum)((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity)),
|
|
1179
|
+
price: this.normalizeFingerprintMoney(bundle == null ? void 0 : bundle.price),
|
|
1180
|
+
bundle_selling_price: this.normalizeFingerprintMoney(bundle == null ? void 0 : bundle.bundle_selling_price),
|
|
1181
|
+
price_type: (bundle == null ? void 0 : bundle.price_type) ?? "",
|
|
1182
|
+
price_type_ext: (bundle == null ? void 0 : bundle.price_type_ext) ?? ""
|
|
1183
|
+
}))),
|
|
1184
|
+
discount_list: this.normalizeFingerprintValue(((product == null ? void 0 : product.discount_list) || []).map((discount) => {
|
|
1185
|
+
var _a;
|
|
1186
|
+
return {
|
|
1187
|
+
type: (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag) ?? "",
|
|
1188
|
+
discount_id: (discount == null ? void 0 : discount.discount_id) ?? (discount == null ? void 0 : discount.order_discount_id) ?? ((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id) ?? null,
|
|
1189
|
+
amount: this.normalizeFingerprintMoney(discount == null ? void 0 : discount.amount)
|
|
1190
|
+
};
|
|
1191
|
+
}))
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
buildOrderProductsFingerprint(products) {
|
|
1195
|
+
const items = (products || []).map((product) => this.buildProductFingerprintItem(product));
|
|
1196
|
+
items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
1197
|
+
return JSON.stringify(items);
|
|
1198
|
+
}
|
|
1199
|
+
buildProductStructuralFingerprintItem(product) {
|
|
1200
|
+
const sku = (product == null ? void 0 : product.product_sku) || {};
|
|
1201
|
+
const metadata = (product == null ? void 0 : product.metadata) || {};
|
|
1202
|
+
const discountTypes = ((product == null ? void 0 : product.discount_list) || []).map((discount) => (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag));
|
|
1203
|
+
const extensionType = (product == null ? void 0 : product.extension_type) || (discountTypes.includes("good_pass") ? "good_pass" : "normal");
|
|
1204
|
+
return {
|
|
1205
|
+
product_id: (product == null ? void 0 : product.product_id) ?? null,
|
|
1206
|
+
product_variant_id: (product == null ? void 0 : product.product_variant_id) ?? null,
|
|
1207
|
+
extension_type: extensionType,
|
|
1208
|
+
num: (0, import_utils3.getSafeProductNum)((product == null ? void 0 : product.num) ?? (product == null ? void 0 : product.product_quantity)),
|
|
1209
|
+
metadata: {
|
|
1210
|
+
unique_identification_number: metadata.unique_identification_number ?? (product == null ? void 0 : product.unique_identification_number) ?? "",
|
|
1211
|
+
price_override: metadata.price_override ?? "",
|
|
1212
|
+
is_manual_discount: metadata.is_manual_discount ?? "",
|
|
1213
|
+
product_discount_reason: metadata.product_discount_reason ?? ""
|
|
1214
|
+
},
|
|
1215
|
+
product_sku: this.normalizeFingerprintValue({
|
|
1216
|
+
code: sku.code ?? "",
|
|
1217
|
+
barcode: sku.barcode ?? "",
|
|
1218
|
+
variant_id: sku.variant_id ?? (product == null ? void 0 : product.product_variant_id) ?? 0,
|
|
1219
|
+
variant: sku.variant || [],
|
|
1220
|
+
option: (0, import_utils.getProductSkuOptions)(product || {}).map((option) => ({
|
|
1221
|
+
id: (option == null ? void 0 : option.id) ?? (option == null ? void 0 : option.option_group_item_id) ?? null,
|
|
1222
|
+
option_group_id: (option == null ? void 0 : option.option_group_id) ?? null,
|
|
1223
|
+
option_group_item_id: (option == null ? void 0 : option.option_group_item_id) ?? (option == null ? void 0 : option.id) ?? null,
|
|
1224
|
+
num: Number((option == null ? void 0 : option.num) ?? 1) || 1,
|
|
1225
|
+
add_price: this.normalizeFingerprintMoney((option == null ? void 0 : option.add_price) ?? (option == null ? void 0 : option.price))
|
|
1226
|
+
}))
|
|
1227
|
+
}),
|
|
1228
|
+
product_bundle: this.normalizeFingerprintValue(((product == null ? void 0 : product.product_bundle) || []).map((bundle) => ({
|
|
1229
|
+
bundle_id: (bundle == null ? void 0 : bundle.bundle_id) ?? (bundle == null ? void 0 : bundle.id) ?? null,
|
|
1230
|
+
bundle_group_id: (bundle == null ? void 0 : bundle.bundle_group_id) ?? (bundle == null ? void 0 : bundle.group_id) ?? null,
|
|
1231
|
+
bundle_product_id: (bundle == null ? void 0 : bundle.bundle_product_id) ?? (bundle == null ? void 0 : bundle._bundle_product_id) ?? (bundle == null ? void 0 : bundle.product_id) ?? null,
|
|
1232
|
+
bundle_variant_id: (bundle == null ? void 0 : bundle.bundle_variant_id) ?? (bundle == null ? void 0 : bundle.product_variant_id) ?? 0,
|
|
1233
|
+
num: (0, import_utils3.getSafeProductNum)((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity)),
|
|
1234
|
+
price_type: (bundle == null ? void 0 : bundle.price_type) ?? "",
|
|
1235
|
+
price_type_ext: (bundle == null ? void 0 : bundle.price_type_ext) ?? "",
|
|
1236
|
+
option: this.normalizeFingerprintValue(((bundle == null ? void 0 : bundle.option) || []).map((option) => ({
|
|
1237
|
+
id: (option == null ? void 0 : option.id) ?? (option == null ? void 0 : option.option_group_item_id) ?? null,
|
|
1238
|
+
option_group_id: (option == null ? void 0 : option.option_group_id) ?? null,
|
|
1239
|
+
option_group_item_id: (option == null ? void 0 : option.option_group_item_id) ?? (option == null ? void 0 : option.id) ?? null,
|
|
1240
|
+
num: Number((option == null ? void 0 : option.num) ?? 1) || 1,
|
|
1241
|
+
add_price: this.normalizeFingerprintMoney((option == null ? void 0 : option.add_price) ?? (option == null ? void 0 : option.price))
|
|
1242
|
+
})))
|
|
1243
|
+
}))),
|
|
1244
|
+
discount_list: this.normalizeFingerprintValue(((product == null ? void 0 : product.discount_list) || []).map((discount) => {
|
|
1245
|
+
var _a;
|
|
1246
|
+
return {
|
|
1247
|
+
type: (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag) ?? "",
|
|
1248
|
+
discount_id: (discount == null ? void 0 : discount.discount_id) ?? (discount == null ? void 0 : discount.order_discount_id) ?? ((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id) ?? null,
|
|
1249
|
+
amount: this.normalizeFingerprintMoney(discount == null ? void 0 : discount.amount)
|
|
1250
|
+
};
|
|
1251
|
+
}))
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
buildOrderProductsStructuralFingerprint(products) {
|
|
1255
|
+
const items = (products || []).map((product) => this.buildProductStructuralFingerprintItem(product));
|
|
1256
|
+
items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
1257
|
+
return JSON.stringify(items);
|
|
1258
|
+
}
|
|
1259
|
+
getOriginalSalesSnapshot(tempOrder) {
|
|
1260
|
+
var _a;
|
|
1261
|
+
const snapshot = (_a = tempOrder._extend) == null ? void 0 : _a.originalSalesSnapshot;
|
|
1262
|
+
if (!snapshot || typeof snapshot !== "object")
|
|
1263
|
+
return null;
|
|
1264
|
+
if (typeof snapshot.productFingerprint !== "string")
|
|
1265
|
+
return null;
|
|
1266
|
+
return snapshot;
|
|
1267
|
+
}
|
|
1268
|
+
isSnapshotPayableAmountUnchanged(tempOrder, snapshot, snapshotSummary) {
|
|
1269
|
+
const currentPaidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1270
|
+
const currentAmountGap = this.calculateSummaryAmountGap({
|
|
1271
|
+
tempOrder,
|
|
1272
|
+
summary: snapshotSummary,
|
|
1273
|
+
orderPaidAmount: currentPaidPaymentSummary.gapPaidAmount
|
|
1274
|
+
});
|
|
1275
|
+
const snapshotPaidPaymentSummary = this.calculatePaidPaymentSummary(
|
|
1276
|
+
Array.isArray(snapshot.payments) ? snapshot.payments : []
|
|
1277
|
+
);
|
|
1278
|
+
const snapshotAmountGap = this.calculateSummaryAmountGap({
|
|
1279
|
+
tempOrder,
|
|
1280
|
+
summary: snapshotSummary,
|
|
1281
|
+
orderPaidAmount: snapshotPaidPaymentSummary.gapPaidAmount
|
|
1282
|
+
});
|
|
1283
|
+
return currentAmountGap === snapshotAmountGap;
|
|
1284
|
+
}
|
|
1285
|
+
restoreOriginalSnapshotIfProductsUnchanged(tempOrder) {
|
|
1286
|
+
const snapshot = this.getOriginalSalesSnapshot(tempOrder);
|
|
1287
|
+
if (!snapshot)
|
|
1288
|
+
return null;
|
|
1289
|
+
const currentFingerprint = this.buildOrderProductsFingerprint(tempOrder.products);
|
|
1290
|
+
if (currentFingerprint !== snapshot.productFingerprint) {
|
|
1291
|
+
const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
|
|
1292
|
+
const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(
|
|
1293
|
+
Array.isArray(snapshot.products) ? snapshot.products : []
|
|
1294
|
+
);
|
|
1295
|
+
if (currentStructuralFingerprint !== snapshotStructuralFingerprint)
|
|
1296
|
+
return null;
|
|
1297
|
+
}
|
|
1298
|
+
const summary = {
|
|
1299
|
+
...(0, import_utils.createEmptySummary)(),
|
|
1300
|
+
...(0, import_lodash_es.cloneDeep)(snapshot.summary || {})
|
|
1301
|
+
};
|
|
1302
|
+
if (!this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary))
|
|
1303
|
+
return null;
|
|
1304
|
+
if (Array.isArray(snapshot.products)) {
|
|
1305
|
+
tempOrder.products = (0, import_lodash_es.cloneDeep)(snapshot.products);
|
|
1306
|
+
}
|
|
1307
|
+
if (Array.isArray(snapshot.surcharges)) {
|
|
1308
|
+
tempOrder.surcharges = (0, import_lodash_es.cloneDeep)(snapshot.surcharges);
|
|
1309
|
+
}
|
|
1310
|
+
tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
|
|
1311
|
+
tempOrder.deposit_amount = summary.deposit_amount || "0.00";
|
|
1312
|
+
tempOrder.is_deposit = summary.deposit_amount !== "0.00" ? 1 : 0;
|
|
1313
|
+
this.store.summary = summary;
|
|
1314
|
+
return summary;
|
|
1315
|
+
}
|
|
1316
|
+
clearPersistedAmountFieldsForFullRecalc(products) {
|
|
1317
|
+
const moneyKeys = [
|
|
1318
|
+
"surcharge_fee",
|
|
1319
|
+
"main_product_attached_bundle_surcharge_fee",
|
|
1320
|
+
"surcharge_rounding_remainder",
|
|
1321
|
+
"main_product_attached_bundle_tax_fee",
|
|
1322
|
+
"tax_fee",
|
|
1323
|
+
"original_tax_fee",
|
|
1324
|
+
"tax_fee_rounding_remainder",
|
|
1325
|
+
"original_tax_fee_rounding_remainder"
|
|
1326
|
+
];
|
|
1327
|
+
const metadataMoneyKeys = [
|
|
1328
|
+
"main_product_attached_bundle_surcharge_fee",
|
|
1329
|
+
"surcharge_rounding_remainder",
|
|
1330
|
+
"main_product_attached_bundle_tax_fee",
|
|
1331
|
+
"tax_fee_rounding_remainder"
|
|
1332
|
+
];
|
|
1333
|
+
for (const product of products || []) {
|
|
1334
|
+
const record = product;
|
|
1335
|
+
for (const key of moneyKeys)
|
|
1336
|
+
delete record[key];
|
|
1337
|
+
if (record.metadata && typeof record.metadata === "object") {
|
|
1338
|
+
record.metadata = { ...record.metadata };
|
|
1339
|
+
for (const key of metadataMoneyKeys)
|
|
1340
|
+
delete record.metadata[key];
|
|
1341
|
+
}
|
|
1342
|
+
for (const bundle of record.product_bundle || []) {
|
|
1343
|
+
for (const key of moneyKeys)
|
|
1344
|
+
delete bundle[key];
|
|
1345
|
+
if (bundle.metadata && typeof bundle.metadata === "object") {
|
|
1346
|
+
bundle.metadata = { ...bundle.metadata };
|
|
1347
|
+
for (const key of metadataMoneyKeys)
|
|
1348
|
+
delete bundle.metadata[key];
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
540
1353
|
getPaymentTargetAmount() {
|
|
541
1354
|
const tempOrder = this.ensureTempOrder();
|
|
542
1355
|
const summary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
)
|
|
547
|
-
|
|
548
|
-
|
|
1356
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1357
|
+
const refundAmount = this.getSummaryRefundAmount(summary);
|
|
1358
|
+
const netPaidAmount = import_decimal.default.max(
|
|
1359
|
+
paidPaymentSummary.gapPaidAmount.minus(refundAmount),
|
|
1360
|
+
0
|
|
1361
|
+
);
|
|
1362
|
+
return this.calculatePaymentTargetAmount(tempOrder, summary, netPaidAmount);
|
|
549
1363
|
}
|
|
550
1364
|
ensureTempOrder() {
|
|
551
1365
|
if (this.store.tempOrder) {
|
|
@@ -559,17 +1373,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
559
1373
|
return newOrder;
|
|
560
1374
|
}
|
|
561
1375
|
restoreOrder() {
|
|
1376
|
+
var _a, _b;
|
|
562
1377
|
const freshTempOrder = this.createDefaultTempOrderInstance();
|
|
563
1378
|
this.ensureExternalSaleNumber(freshTempOrder);
|
|
564
1379
|
this.store.tempOrder = freshTempOrder;
|
|
565
1380
|
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
566
1381
|
this.store.lastOrderInfo = void 0;
|
|
1382
|
+
this.store.syncState = void 0;
|
|
1383
|
+
void ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList([]));
|
|
1384
|
+
void ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList([]));
|
|
567
1385
|
this.persistTempOrder();
|
|
568
1386
|
return freshTempOrder;
|
|
569
1387
|
}
|
|
570
1388
|
getTempOrder() {
|
|
571
1389
|
return this.store.tempOrder;
|
|
572
1390
|
}
|
|
1391
|
+
async replaceTempOrder(tempOrder, options) {
|
|
1392
|
+
if (!(0, import_utils.isTempOrder)(tempOrder)) {
|
|
1393
|
+
throw new Error("无效的 tempOrder 数据");
|
|
1394
|
+
}
|
|
1395
|
+
const nextTempOrder = this.normalizeTempOrderForRuntime(
|
|
1396
|
+
(0, import_lodash_es.cloneDeep)(tempOrder),
|
|
1397
|
+
{ ensureIdentity: false }
|
|
1398
|
+
);
|
|
1399
|
+
this.store.tempOrder = nextTempOrder;
|
|
1400
|
+
if ((options == null ? void 0 : options.recalculateSummary) !== false) {
|
|
1401
|
+
await this.recalculateSummary({ createIfMissing: false });
|
|
1402
|
+
} else {
|
|
1403
|
+
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
1404
|
+
}
|
|
1405
|
+
if ((options == null ? void 0 : options.persist) !== false) {
|
|
1406
|
+
this.persistTempOrder();
|
|
1407
|
+
}
|
|
1408
|
+
if (options == null ? void 0 : options.saveDraft) {
|
|
1409
|
+
await this.saveDraft();
|
|
1410
|
+
}
|
|
1411
|
+
return nextTempOrder;
|
|
1412
|
+
}
|
|
573
1413
|
getOrderIdentity() {
|
|
574
1414
|
var _a;
|
|
575
1415
|
const tempOrder = this.store.tempOrder;
|
|
@@ -605,9 +1445,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
605
1445
|
return null;
|
|
606
1446
|
const summary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
607
1447
|
const depositAmount = tempOrder.deposit_amount || summary.deposit_amount || "0.00";
|
|
608
|
-
const
|
|
609
|
-
const
|
|
610
|
-
|
|
1448
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1449
|
+
const amountGap = this.calculateSummaryAmountGap({
|
|
1450
|
+
tempOrder,
|
|
1451
|
+
summary,
|
|
1452
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1453
|
+
});
|
|
611
1454
|
return {
|
|
612
1455
|
isDeposit: tempOrder.is_deposit === 1 || depositAmount !== "0.00",
|
|
613
1456
|
depositAmount,
|
|
@@ -650,7 +1493,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
650
1493
|
this.ensureExternalSaleNumber(tempOrder);
|
|
651
1494
|
await this.recalculateSummary({ createIfMissing: true });
|
|
652
1495
|
this.persistTempOrder();
|
|
653
|
-
|
|
1496
|
+
if (this.draftPersistEnabled) {
|
|
1497
|
+
await this.saveDraft();
|
|
1498
|
+
}
|
|
654
1499
|
return tempOrder;
|
|
655
1500
|
}
|
|
656
1501
|
getOrderProducts() {
|
|
@@ -664,6 +1509,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
664
1509
|
product.metadata = metadata;
|
|
665
1510
|
return String(uid);
|
|
666
1511
|
}
|
|
1512
|
+
sanitizeOrderProductForTempOrder(product) {
|
|
1513
|
+
if (product.metadata && typeof product.metadata === "object") {
|
|
1514
|
+
delete product.metadata.origin;
|
|
1515
|
+
}
|
|
1516
|
+
return product;
|
|
1517
|
+
}
|
|
1518
|
+
sanitizeTempOrderProducts(tempOrder) {
|
|
1519
|
+
tempOrder.products = (tempOrder.products || []).map(
|
|
1520
|
+
(product) => this.sanitizeOrderProductForTempOrder(product)
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
667
1523
|
ensureExtend(tempOrder) {
|
|
668
1524
|
if (!tempOrder._extend || typeof tempOrder._extend !== "object") {
|
|
669
1525
|
tempOrder._extend = { productsByUid: {} };
|
|
@@ -697,6 +1553,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
697
1553
|
);
|
|
698
1554
|
productMetadata.unique_identification_number = productUid;
|
|
699
1555
|
bookingMetadata.unique_identification_number = bookingUid;
|
|
1556
|
+
this.syncBookingMetadataHolder(params.booking, bookingMetadata);
|
|
700
1557
|
return {
|
|
701
1558
|
productUid,
|
|
702
1559
|
bookingUid,
|
|
@@ -718,44 +1575,256 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
718
1575
|
}
|
|
719
1576
|
};
|
|
720
1577
|
}
|
|
1578
|
+
/**
|
|
1579
|
+
* booking.holder 是提交真源;metadata.holder 作为详情/回显冗余字段同步保存。
|
|
1580
|
+
*
|
|
1581
|
+
* @example
|
|
1582
|
+
* this.syncBookingMetadataHolder(booking, metadata);
|
|
1583
|
+
*/
|
|
1584
|
+
syncBookingMetadataHolder(booking, metadata) {
|
|
1585
|
+
if ((booking == null ? void 0 : booking.holder) !== void 0) {
|
|
1586
|
+
metadata.holder = booking.holder;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
/**
|
|
1590
|
+
* 从单条 booking 的 holder / metadata 中收集 holder form_record。
|
|
1591
|
+
*
|
|
1592
|
+
* @example
|
|
1593
|
+
* const ids = this.collectBookingHolderRecords(booking);
|
|
1594
|
+
*/
|
|
1595
|
+
collectBookingHolderRecords(booking) {
|
|
1596
|
+
var _a;
|
|
1597
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1598
|
+
const source = (holder == null ? void 0 : holder.form_record) ?? ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id);
|
|
1599
|
+
const records = Array.isArray(source) ? source : [source];
|
|
1600
|
+
return records.filter((record) => record !== void 0 && record !== null && record !== "");
|
|
1601
|
+
}
|
|
1602
|
+
/**
|
|
1603
|
+
* 按 form_record 顺序读取 booking holder 的主字段名称。
|
|
1604
|
+
*
|
|
1605
|
+
* @example
|
|
1606
|
+
* const names = this.collectBookingHolderNames(booking);
|
|
1607
|
+
*/
|
|
1608
|
+
collectBookingHolderNames(booking) {
|
|
1609
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1610
|
+
const rawName = holder == null ? void 0 : holder.name;
|
|
1611
|
+
if (Array.isArray(rawName)) {
|
|
1612
|
+
return rawName.map((name) => String(name || "").trim());
|
|
1613
|
+
}
|
|
1614
|
+
if (typeof rawName === "string") {
|
|
1615
|
+
return rawName.split(",").map((name) => name.trim());
|
|
1616
|
+
}
|
|
1617
|
+
return [];
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* 按老 ticketBooking `formatHolder` 语义汇总订单顶层 holder。
|
|
1621
|
+
*
|
|
1622
|
+
* @example
|
|
1623
|
+
* const holder = this.buildTempOrderHolderFromBookings(tempOrder);
|
|
1624
|
+
*/
|
|
1625
|
+
buildTempOrderHolderFromBookings(tempOrder) {
|
|
1626
|
+
var _a, _b;
|
|
1627
|
+
const holderRecords = [];
|
|
1628
|
+
const holderNames = [];
|
|
1629
|
+
let baseHolder = null;
|
|
1630
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1631
|
+
for (const booking of tempOrder.bookings || []) {
|
|
1632
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1633
|
+
if (!baseHolder && holder) {
|
|
1634
|
+
baseHolder = holder;
|
|
1635
|
+
}
|
|
1636
|
+
const records = this.collectBookingHolderRecords(booking);
|
|
1637
|
+
const names = this.collectBookingHolderNames(booking);
|
|
1638
|
+
for (const [index, record] of records.entries()) {
|
|
1639
|
+
const key = String(record);
|
|
1640
|
+
if (seen.has(key))
|
|
1641
|
+
continue;
|
|
1642
|
+
seen.add(key);
|
|
1643
|
+
holderRecords.push(record);
|
|
1644
|
+
if (names[index]) {
|
|
1645
|
+
holderNames.push(names[index]);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
if (!holderRecords.length) {
|
|
1650
|
+
return null;
|
|
1651
|
+
}
|
|
1652
|
+
const nextHolder = {
|
|
1653
|
+
customer_id: (baseHolder == null ? void 0 : baseHolder.customer_id) ?? tempOrder.customer_id,
|
|
1654
|
+
form_id: (baseHolder == null ? void 0 : baseHolder.form_id) ?? ((_a = tempOrder.holder) == null ? void 0 : _a.form_id) ?? 0,
|
|
1655
|
+
form_record: holderRecords
|
|
1656
|
+
};
|
|
1657
|
+
if (holderNames.length) {
|
|
1658
|
+
nextHolder.name = holderNames.join(",");
|
|
1659
|
+
}
|
|
1660
|
+
if ((baseHolder == null ? void 0 : baseHolder.is_source_shop) || ((_b = this.otherParams) == null ? void 0 : _b.isFranchisee)) {
|
|
1661
|
+
nextHolder.is_source_shop = 1;
|
|
1662
|
+
}
|
|
1663
|
+
return nextHolder;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* 将 booking 级 holder 汇总到 tempOrder 顶层 holder。
|
|
1667
|
+
*
|
|
1668
|
+
* @example
|
|
1669
|
+
* this.syncTempOrderHolderFromBookings(tempOrder);
|
|
1670
|
+
*/
|
|
1671
|
+
syncTempOrderHolderFromBookings(tempOrder) {
|
|
1672
|
+
const bookings = tempOrder.bookings || [];
|
|
1673
|
+
const hasHolderSource = bookings.some((booking) => {
|
|
1674
|
+
var _a;
|
|
1675
|
+
return (booking == null ? void 0 : booking.holder) !== void 0 || ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id) !== void 0;
|
|
1676
|
+
});
|
|
1677
|
+
const nextHolder = this.buildTempOrderHolderFromBookings(tempOrder);
|
|
1678
|
+
if (nextHolder || hasHolderSource || bookings.length === 0) {
|
|
1679
|
+
tempOrder.holder = nextHolder;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
getBookingUniqueIdentificationNumber(booking) {
|
|
1683
|
+
var _a;
|
|
1684
|
+
const uid = (_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
1685
|
+
if (uid === void 0 || uid === null || uid === "")
|
|
1686
|
+
return null;
|
|
1687
|
+
return String(uid);
|
|
1688
|
+
}
|
|
1689
|
+
findBookingIndexByUniqueIdentificationNumber(tempOrder, uniqueIdentificationNumber) {
|
|
1690
|
+
return (tempOrder.bookings || []).findIndex((booking) => {
|
|
1691
|
+
return this.getBookingUniqueIdentificationNumber(booking) === uniqueIdentificationNumber;
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
removeLinkedBookingsForProduct(tempOrder, product) {
|
|
1695
|
+
var _a, _b;
|
|
1696
|
+
const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
|
|
1697
|
+
const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.booking_uid);
|
|
1698
|
+
if (!productUid && !bookingUid)
|
|
1699
|
+
return;
|
|
1700
|
+
tempOrder.bookings = (tempOrder.bookings || []).filter((booking) => {
|
|
1701
|
+
const currentBookingUid = this.getBookingUniqueIdentificationNumber(booking);
|
|
1702
|
+
if (bookingUid && currentBookingUid === String(bookingUid))
|
|
1703
|
+
return false;
|
|
1704
|
+
if (productUid && String((booking == null ? void 0 : booking.product_uid) || "") === String(productUid))
|
|
1705
|
+
return false;
|
|
1706
|
+
return true;
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
721
1709
|
// ─── TempOrder: 金额汇总 ───
|
|
722
1710
|
getSalesSummary() {
|
|
723
1711
|
if (!this.salesSummaryModuleName)
|
|
724
1712
|
return null;
|
|
725
1713
|
return this.core.getModule(this.salesSummaryModuleName);
|
|
726
1714
|
}
|
|
1715
|
+
applyOrderProductsDepositSummary(tempOrder, summary) {
|
|
1716
|
+
var _a;
|
|
1717
|
+
const depositSummary = (0, import_utils.calculateOrderProductsDeposit)(tempOrder.products || [], {
|
|
1718
|
+
productsByUid: (_a = tempOrder._extend) == null ? void 0 : _a.productsByUid
|
|
1719
|
+
});
|
|
1720
|
+
const nextSummary = {
|
|
1721
|
+
...summary,
|
|
1722
|
+
deposit_amount: depositSummary.totalText,
|
|
1723
|
+
deposit: depositSummary.hasDeposit ? {
|
|
1724
|
+
total: depositSummary.totalText,
|
|
1725
|
+
deposit_policy_ids: depositSummary.deposit_policy_ids,
|
|
1726
|
+
deposit_policy_data: depositSummary.protocols,
|
|
1727
|
+
hasDeposit: true
|
|
1728
|
+
} : void 0
|
|
1729
|
+
};
|
|
1730
|
+
tempOrder.deposit_amount = depositSummary.totalText;
|
|
1731
|
+
tempOrder.is_deposit = depositSummary.hasDeposit ? 1 : 0;
|
|
1732
|
+
return nextSummary;
|
|
1733
|
+
}
|
|
727
1734
|
async recalculateSummary(options) {
|
|
728
1735
|
const tempOrder = (options == null ? void 0 : options.createIfMissing) ? this.ensureTempOrder() : this.store.tempOrder;
|
|
729
1736
|
if (!tempOrder)
|
|
730
1737
|
return null;
|
|
1738
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1739
|
+
const snapshotSummary = this.restoreOriginalSnapshotIfProductsUnchanged(tempOrder);
|
|
1740
|
+
if (snapshotSummary)
|
|
1741
|
+
return snapshotSummary;
|
|
1742
|
+
const shouldFullRecalculateFromSnapshot = Boolean(this.getOriginalSalesSnapshot(tempOrder));
|
|
1743
|
+
const summaryProducts = shouldFullRecalculateFromSnapshot ? (0, import_lodash_es.cloneDeep)(tempOrder.products || []) : tempOrder.products;
|
|
1744
|
+
if (shouldFullRecalculateFromSnapshot) {
|
|
1745
|
+
this.clearPersistedAmountFieldsForFullRecalc(summaryProducts || []);
|
|
1746
|
+
}
|
|
731
1747
|
const salesSummary = this.getSalesSummary();
|
|
732
1748
|
const existedSummary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1749
|
+
const totalRefundAmount = existedSummary.total_refund_amount || "0.00";
|
|
733
1750
|
const paidPaymentSummary = this.calculatePaidPaymentSummary(
|
|
734
1751
|
tempOrder.payments || []
|
|
735
1752
|
);
|
|
736
1753
|
if (!salesSummary) {
|
|
737
|
-
const
|
|
1754
|
+
const emptyBaseSummary = {
|
|
738
1755
|
...(0, import_utils.createEmptySummary)(),
|
|
739
|
-
|
|
1756
|
+
...existedSummary,
|
|
1757
|
+
total_refund_amount: totalRefundAmount
|
|
1758
|
+
};
|
|
1759
|
+
const emptySummaryBase = {
|
|
1760
|
+
...emptyBaseSummary,
|
|
740
1761
|
customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
|
|
741
1762
|
order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
|
|
742
|
-
pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
|
|
1763
|
+
pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2),
|
|
1764
|
+
rounding_amount: paidPaymentSummary.roundingAmount.toFixed(2)
|
|
1765
|
+
};
|
|
1766
|
+
const emptySummaryWithDeposit = this.applyOrderProductsDepositSummary(
|
|
1767
|
+
tempOrder,
|
|
1768
|
+
emptySummaryBase
|
|
1769
|
+
);
|
|
1770
|
+
const emptySummary = {
|
|
1771
|
+
...emptySummaryWithDeposit,
|
|
1772
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1773
|
+
tempOrder,
|
|
1774
|
+
summary: emptySummaryWithDeposit,
|
|
1775
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1776
|
+
})
|
|
743
1777
|
};
|
|
744
|
-
this.store.summary = emptySummary;
|
|
745
1778
|
tempOrder.surcharge_fee = emptySummary.surcharge_fee;
|
|
1779
|
+
this.store.summary = emptySummary;
|
|
1780
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1781
|
+
previousSummary: existedSummary,
|
|
1782
|
+
summary: emptySummary
|
|
1783
|
+
});
|
|
746
1784
|
return this.store.summary;
|
|
747
1785
|
}
|
|
748
1786
|
const salesSummaryResult = await salesSummary.getSummary({
|
|
749
|
-
products:
|
|
1787
|
+
products: summaryProducts,
|
|
750
1788
|
isPriceIncludeTax: tempOrder.is_price_include_tax,
|
|
751
1789
|
shopDiscount: tempOrder.shop_discount
|
|
752
1790
|
});
|
|
753
|
-
|
|
1791
|
+
if (shouldFullRecalculateFromSnapshot) {
|
|
1792
|
+
tempOrder.products = summaryProducts;
|
|
1793
|
+
}
|
|
1794
|
+
this.syncSummaryProductMetadata(tempOrder.products || []);
|
|
1795
|
+
const roundingAmount = paidPaymentSummary.roundingAmount;
|
|
1796
|
+
const payServiceChargeAmount = paidPaymentSummary.payServiceChargeAmount;
|
|
1797
|
+
const hasSalesSummaryAmount = salesSummaryResult.expect_amount !== void 0 || salesSummaryResult.total_amount !== void 0;
|
|
1798
|
+
const expectAmount = hasSalesSummaryAmount ? new import_decimal.default(salesSummaryResult.expect_amount ?? salesSummaryResult.total_amount ?? 0) : null;
|
|
1799
|
+
const amountPaymentPatch = hasSalesSummaryAmount || !roundingAmount.eq(0) || !payServiceChargeAmount.eq(0) ? {
|
|
1800
|
+
rounding_amount: roundingAmount.toFixed(2),
|
|
1801
|
+
...expectAmount ? {
|
|
1802
|
+
total_amount: import_decimal.default.max(
|
|
1803
|
+
0,
|
|
1804
|
+
expectAmount.plus(roundingAmount).plus(payServiceChargeAmount)
|
|
1805
|
+
).toFixed(2)
|
|
1806
|
+
} : {}
|
|
1807
|
+
} : {};
|
|
1808
|
+
const normalizedExpectAmountPatch = expectAmount && salesSummaryResult.expect_amount === void 0 ? { expect_amount: expectAmount.toFixed(2) } : {};
|
|
1809
|
+
const summaryForGap = this.applyOrderProductsDepositSummary(tempOrder, {
|
|
754
1810
|
...salesSummaryResult,
|
|
755
|
-
total_refund_amount:
|
|
1811
|
+
total_refund_amount: totalRefundAmount,
|
|
1812
|
+
...amountPaymentPatch,
|
|
1813
|
+
...normalizedExpectAmountPatch
|
|
1814
|
+
});
|
|
1815
|
+
const summary = {
|
|
1816
|
+
...summaryForGap,
|
|
1817
|
+
total_refund_amount: totalRefundAmount,
|
|
756
1818
|
customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
|
|
757
1819
|
order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
|
|
758
|
-
|
|
1820
|
+
...amountPaymentPatch,
|
|
1821
|
+
...normalizedExpectAmountPatch,
|
|
1822
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1823
|
+
tempOrder,
|
|
1824
|
+
summary: summaryForGap,
|
|
1825
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1826
|
+
}),
|
|
1827
|
+
pay_service_charge_amount: payServiceChargeAmount.toFixed(2)
|
|
759
1828
|
};
|
|
760
1829
|
this.store.summary = summary;
|
|
761
1830
|
if (summary.is_price_include_tax !== void 0) {
|
|
@@ -766,8 +1835,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
766
1835
|
}
|
|
767
1836
|
tempOrder.surcharge_fee = summary.surcharge_fee;
|
|
768
1837
|
tempOrder.surcharges = summary.surcharges || [];
|
|
769
|
-
tempOrder
|
|
770
|
-
|
|
1838
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1839
|
+
previousSummary: existedSummary,
|
|
1840
|
+
summary
|
|
1841
|
+
});
|
|
771
1842
|
return this.store.summary;
|
|
772
1843
|
}
|
|
773
1844
|
async getOrderSummary() {
|
|
@@ -777,13 +1848,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
777
1848
|
this.persistTempOrder();
|
|
778
1849
|
return summary;
|
|
779
1850
|
}
|
|
780
|
-
|
|
781
|
-
updateTempOrderNote(note) {
|
|
1851
|
+
updateTempOrderNote(note, sync = false) {
|
|
782
1852
|
const tempOrder = this.ensureTempOrder();
|
|
783
1853
|
tempOrder.note = String(note || "");
|
|
784
1854
|
this.persistTempOrder();
|
|
1855
|
+
if (sync) {
|
|
1856
|
+
const orderId = tempOrder.order_id;
|
|
1857
|
+
if (!orderId)
|
|
1858
|
+
return tempOrder.note;
|
|
1859
|
+
return this.syncTempOrderNoteToRemote(orderId, tempOrder.note);
|
|
1860
|
+
}
|
|
785
1861
|
return tempOrder.note;
|
|
786
1862
|
}
|
|
1863
|
+
async syncTempOrderNoteToRemote(orderId, note) {
|
|
1864
|
+
await this.request.put(`/order/order/${orderId}/note`, { note });
|
|
1865
|
+
return note;
|
|
1866
|
+
}
|
|
787
1867
|
getTempOrderNote() {
|
|
788
1868
|
var _a;
|
|
789
1869
|
return ((_a = this.store.tempOrder) == null ? void 0 : _a.note) || "";
|
|
@@ -795,6 +1875,35 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
795
1875
|
this.persistTempOrder();
|
|
796
1876
|
return tempOrder.shop_discount;
|
|
797
1877
|
}
|
|
1878
|
+
updateTempOrderDepositAmount(amount) {
|
|
1879
|
+
const tempOrder = this.ensureTempOrder();
|
|
1880
|
+
const depositAmount = this.normalizeDepositAmount(amount);
|
|
1881
|
+
const previousSummary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1882
|
+
const summaryWithDeposit = this.applyDepositAmountToSummary(
|
|
1883
|
+
tempOrder,
|
|
1884
|
+
{
|
|
1885
|
+
...(0, import_utils.createEmptySummary)(),
|
|
1886
|
+
...previousSummary
|
|
1887
|
+
},
|
|
1888
|
+
depositAmount
|
|
1889
|
+
);
|
|
1890
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1891
|
+
const summary = {
|
|
1892
|
+
...summaryWithDeposit,
|
|
1893
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1894
|
+
tempOrder,
|
|
1895
|
+
summary: summaryWithDeposit,
|
|
1896
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1897
|
+
})
|
|
1898
|
+
};
|
|
1899
|
+
this.store.summary = summary;
|
|
1900
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1901
|
+
previousSummary,
|
|
1902
|
+
summary
|
|
1903
|
+
});
|
|
1904
|
+
this.persistTempOrder();
|
|
1905
|
+
return summary;
|
|
1906
|
+
}
|
|
798
1907
|
updateTempOrderBuzzer(buzzer) {
|
|
799
1908
|
const tempOrder = this.ensureTempOrder();
|
|
800
1909
|
tempOrder.buzzer = String(buzzer || "");
|
|
@@ -807,14 +1916,77 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
807
1916
|
this.persistTempOrder();
|
|
808
1917
|
return tempOrder.contacts_info;
|
|
809
1918
|
}
|
|
1919
|
+
buildTempOrderCustomer(params) {
|
|
1920
|
+
if (!params.customerId)
|
|
1921
|
+
return null;
|
|
1922
|
+
const source = params.source ? (0, import_lodash_es.cloneDeep)(params.source) : {};
|
|
1923
|
+
const name = source.name ?? source.display_name ?? source.customerName ?? source.customer_name ?? params.customerName;
|
|
1924
|
+
const customerName = source.customer_name ?? source.customerName ?? source.display_name ?? source.name ?? params.customerName;
|
|
1925
|
+
return {
|
|
1926
|
+
...source,
|
|
1927
|
+
id: source.id ?? params.customerId,
|
|
1928
|
+
customer_id: source.customer_id ?? params.customerId,
|
|
1929
|
+
name: String(name || ""),
|
|
1930
|
+
customer_name: String(customerName || ""),
|
|
1931
|
+
country_calling_code: String(
|
|
1932
|
+
source.country_calling_code ?? source.countryCallingCode ?? params.countryCallingCode
|
|
1933
|
+
),
|
|
1934
|
+
phone: String(source.phone ?? params.phone),
|
|
1935
|
+
email: String(source.email ?? params.email)
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1938
|
+
isCustomerBoundDiscount(discount) {
|
|
1939
|
+
const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
|
|
1940
|
+
return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
|
|
1941
|
+
}
|
|
1942
|
+
clearCustomerBoundDiscounts(tempOrder) {
|
|
1943
|
+
var _a, _b, _c, _d;
|
|
1944
|
+
const filterDiscountList = (discountList) => {
|
|
1945
|
+
if (!Array.isArray(discountList))
|
|
1946
|
+
return [];
|
|
1947
|
+
return discountList.filter((discount) => !this.isCustomerBoundDiscount(discount));
|
|
1948
|
+
};
|
|
1949
|
+
tempOrder.products = (tempOrder.products || []).map((product) => {
|
|
1950
|
+
const nextProduct = {
|
|
1951
|
+
...product,
|
|
1952
|
+
discount_list: filterDiscountList(product.discount_list)
|
|
1953
|
+
};
|
|
1954
|
+
if (Array.isArray(nextProduct.product_bundle)) {
|
|
1955
|
+
nextProduct.product_bundle = nextProduct.product_bundle.map((bundle) => ({
|
|
1956
|
+
...bundle,
|
|
1957
|
+
discount_list: filterDiscountList(bundle.discount_list)
|
|
1958
|
+
}));
|
|
1959
|
+
}
|
|
1960
|
+
return nextProduct;
|
|
1961
|
+
});
|
|
1962
|
+
delete tempOrder.discount_list;
|
|
1963
|
+
const discountModule = this.store.discount;
|
|
1964
|
+
if (!discountModule)
|
|
1965
|
+
return;
|
|
1966
|
+
const currentDiscounts = ((_a = discountModule.getDiscountList) == null ? void 0 : _a.call(discountModule)) || [];
|
|
1967
|
+
const currentOriginalDiscounts = ((_b = discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
|
|
1968
|
+
const nextDiscounts = currentDiscounts.filter((discount) => {
|
|
1969
|
+
if (discount == null ? void 0 : discount.isEditMode)
|
|
1970
|
+
return true;
|
|
1971
|
+
return !this.isCustomerBoundDiscount(discount);
|
|
1972
|
+
});
|
|
1973
|
+
const nextOriginalDiscounts = currentOriginalDiscounts.filter((discount) => {
|
|
1974
|
+
if (discount == null ? void 0 : discount.isEditMode)
|
|
1975
|
+
return true;
|
|
1976
|
+
return !this.isCustomerBoundDiscount(discount);
|
|
1977
|
+
});
|
|
1978
|
+
void ((_c = discountModule.setDiscountList) == null ? void 0 : _c.call(discountModule, nextDiscounts));
|
|
1979
|
+
void ((_d = discountModule.setOriginalDiscountList) == null ? void 0 : _d.call(discountModule, nextOriginalDiscounts));
|
|
1980
|
+
}
|
|
810
1981
|
/**
|
|
811
1982
|
* 更新当前 tempOrder 的客户协议字段。
|
|
812
1983
|
*
|
|
813
|
-
* PaymentModal
|
|
1984
|
+
* PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
|
|
814
1985
|
* 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
|
|
815
1986
|
*/
|
|
816
1987
|
updateTempOrderCustomer(customer) {
|
|
817
1988
|
const tempOrder = this.ensureTempOrder();
|
|
1989
|
+
const previousCustomerId = tempOrder.customer_id ?? null;
|
|
818
1990
|
const customerId = customer.customer_id ?? customer.customerId ?? customer.id ?? null;
|
|
819
1991
|
const customerName = customer.customer_name ?? customer.customerName ?? customer.display_name ?? customer.name ?? "";
|
|
820
1992
|
tempOrder.customer_id = customerId === null || customerId === void 0 || customerId === "" ? null : Number(customerId);
|
|
@@ -824,6 +1996,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
824
1996
|
);
|
|
825
1997
|
tempOrder.phone = String(customer.phone || "");
|
|
826
1998
|
tempOrder.email = String(customer.email || "");
|
|
1999
|
+
tempOrder.customer = this.buildTempOrderCustomer({
|
|
2000
|
+
source: customer,
|
|
2001
|
+
customerId: tempOrder.customer_id,
|
|
2002
|
+
customerName: tempOrder.customer_name,
|
|
2003
|
+
countryCallingCode: tempOrder.country_calling_code,
|
|
2004
|
+
phone: tempOrder.phone,
|
|
2005
|
+
email: tempOrder.email
|
|
2006
|
+
});
|
|
2007
|
+
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
827
2008
|
this.persistTempOrder();
|
|
828
2009
|
return {
|
|
829
2010
|
customerId: tempOrder.customer_id,
|
|
@@ -838,11 +2019,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
838
2019
|
return;
|
|
839
2020
|
}
|
|
840
2021
|
const tempOrder = this.ensureTempOrder();
|
|
2022
|
+
const previousCustomerId = tempOrder.customer_id ?? null;
|
|
841
2023
|
tempOrder.customer_id = patch.customer_id || patch.id || null;
|
|
842
2024
|
tempOrder.customer_name = String(patch.customer_name || "");
|
|
843
2025
|
tempOrder.country_calling_code = String(patch.country_calling_code || "");
|
|
844
2026
|
tempOrder.phone = String(patch.phone || "");
|
|
845
2027
|
tempOrder.email = String(patch.email || "");
|
|
2028
|
+
tempOrder.customer = this.buildTempOrderCustomer({
|
|
2029
|
+
source: snapshot || null,
|
|
2030
|
+
customerId: tempOrder.customer_id,
|
|
2031
|
+
customerName: tempOrder.customer_name,
|
|
2032
|
+
countryCallingCode: tempOrder.country_calling_code,
|
|
2033
|
+
phone: tempOrder.phone,
|
|
2034
|
+
email: tempOrder.email
|
|
2035
|
+
});
|
|
846
2036
|
if (snapshot !== void 0) {
|
|
847
2037
|
const extend = this.ensureExtend(tempOrder);
|
|
848
2038
|
if (snapshot === null)
|
|
@@ -850,12 +2040,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
850
2040
|
else
|
|
851
2041
|
extend.customerSnapshot = (0, import_lodash_es.cloneDeep)(snapshot);
|
|
852
2042
|
}
|
|
2043
|
+
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
2044
|
+
if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
|
|
2045
|
+
(0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
|
|
2046
|
+
this.clearCustomerBoundDiscounts(tempOrder);
|
|
2047
|
+
}
|
|
853
2048
|
this.persistTempOrder();
|
|
854
|
-
this.
|
|
2049
|
+
this.saveDraftInBackground();
|
|
2050
|
+
if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
|
|
2051
|
+
this.emitOrderCustomerChange();
|
|
2052
|
+
}
|
|
855
2053
|
}
|
|
856
2054
|
getOrderCustomer() {
|
|
857
2055
|
const tempOrder = this.store.tempOrder;
|
|
858
|
-
if (!tempOrder || tempOrder.customer_id
|
|
2056
|
+
if (!tempOrder || !tempOrder.customer_id) {
|
|
859
2057
|
return null;
|
|
860
2058
|
}
|
|
861
2059
|
return {
|
|
@@ -873,14 +2071,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
873
2071
|
}
|
|
874
2072
|
clearOrderCustomer() {
|
|
875
2073
|
const tempOrder = this.ensureTempOrder();
|
|
2074
|
+
(0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
|
|
876
2075
|
tempOrder.customer_id = null;
|
|
877
2076
|
tempOrder.customer_name = "";
|
|
878
2077
|
tempOrder.country_calling_code = "";
|
|
879
2078
|
tempOrder.phone = "";
|
|
880
2079
|
tempOrder.email = "";
|
|
2080
|
+
tempOrder.customer = null;
|
|
881
2081
|
if (tempOrder._extend)
|
|
882
2082
|
delete tempOrder._extend.customerSnapshot;
|
|
2083
|
+
this.clearCustomerBoundDiscounts(tempOrder);
|
|
883
2084
|
this.persistTempOrder();
|
|
2085
|
+
this.saveDraftInBackground();
|
|
884
2086
|
this.core.effects.emit(import_types.OrderHooks.OnOrderCustomerChange, null);
|
|
885
2087
|
}
|
|
886
2088
|
emitOrderCustomerChange() {
|
|
@@ -920,10 +2122,28 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
920
2122
|
}
|
|
921
2123
|
/** 追加单个支付项,并立即持久化当前 tempOrder。 */
|
|
922
2124
|
addOrderPayment(payment) {
|
|
2125
|
+
this.logInfo("addOrderPayment", {
|
|
2126
|
+
payment
|
|
2127
|
+
});
|
|
923
2128
|
const tempOrder = this.ensureTempOrder();
|
|
924
|
-
const
|
|
2129
|
+
const orderPaymentType = this.resolveNextOrderPaymentType(tempOrder);
|
|
2130
|
+
const mapped = (0, import_utils.mapPaymentItemsToOrderPayments)([
|
|
2131
|
+
this.normalizePaymentSource(
|
|
2132
|
+
{
|
|
2133
|
+
...payment,
|
|
2134
|
+
type: orderPaymentType,
|
|
2135
|
+
order_payment_type: orderPaymentType
|
|
2136
|
+
},
|
|
2137
|
+
{ defaultPaid: true }
|
|
2138
|
+
)
|
|
2139
|
+
]);
|
|
925
2140
|
tempOrder.payments = [...tempOrder.payments || [], ...mapped];
|
|
926
2141
|
this.persistTempOrder();
|
|
2142
|
+
void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
|
|
2143
|
+
this.logError("recalculate summary after addOrderPayment failed", {
|
|
2144
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2145
|
+
});
|
|
2146
|
+
});
|
|
927
2147
|
return tempOrder.payments;
|
|
928
2148
|
}
|
|
929
2149
|
/**
|
|
@@ -989,14 +2209,48 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
989
2209
|
*/
|
|
990
2210
|
updateVoucherOrderPayments(payments) {
|
|
991
2211
|
const tempOrder = this.ensureTempOrder();
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
|
|
2212
|
+
const isVoucherPayment = (payment) => {
|
|
2213
|
+
return payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0;
|
|
2214
|
+
};
|
|
2215
|
+
const hasSyncedOrderPayment = (payment) => {
|
|
2216
|
+
return payment.order_payment_id !== void 0 && payment.order_payment_id !== null;
|
|
2217
|
+
};
|
|
2218
|
+
const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(
|
|
2219
|
+
payments.map(
|
|
2220
|
+
(payment) => this.normalizePaymentSource(payment, { defaultPaid: true })
|
|
2221
|
+
)
|
|
2222
|
+
).filter((payment) => {
|
|
2223
|
+
return isVoucherPayment(payment);
|
|
2224
|
+
});
|
|
995
2225
|
const nonVoucherPayments = (tempOrder.payments || []).filter((payment) => {
|
|
996
|
-
return
|
|
2226
|
+
return !isVoucherPayment(payment);
|
|
997
2227
|
});
|
|
998
|
-
tempOrder.payments
|
|
2228
|
+
const syncedVoucherPayments = (tempOrder.payments || []).filter((payment) => {
|
|
2229
|
+
return isVoucherPayment(payment) && hasSyncedOrderPayment(payment);
|
|
2230
|
+
});
|
|
2231
|
+
const syncedVoucherPaymentIds = new Set(
|
|
2232
|
+
syncedVoucherPayments.map((payment) => String(payment.order_payment_id))
|
|
2233
|
+
);
|
|
2234
|
+
const replaceableVouchers = mappedVouchers.filter((payment) => {
|
|
2235
|
+
if (!hasSyncedOrderPayment(payment))
|
|
2236
|
+
return true;
|
|
2237
|
+
return !syncedVoucherPaymentIds.has(String(payment.order_payment_id));
|
|
2238
|
+
});
|
|
2239
|
+
const cappedVouchers = this.capVoucherPaymentsByRemainingAmount({
|
|
2240
|
+
vouchers: replaceableVouchers,
|
|
2241
|
+
nonVoucherPayments: [
|
|
2242
|
+
...nonVoucherPayments,
|
|
2243
|
+
...syncedVoucherPayments
|
|
2244
|
+
]
|
|
2245
|
+
});
|
|
2246
|
+
tempOrder.payments = [...nonVoucherPayments, ...syncedVoucherPayments, ...cappedVouchers];
|
|
2247
|
+
this.updateTempOrderPaymentStatus(tempOrder);
|
|
999
2248
|
this.persistTempOrder();
|
|
2249
|
+
void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
|
|
2250
|
+
this.logError("recalculate summary after updateVoucherOrderPayments failed", {
|
|
2251
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2252
|
+
});
|
|
2253
|
+
});
|
|
1000
2254
|
return tempOrder.payments;
|
|
1001
2255
|
}
|
|
1002
2256
|
async shouldMergeProductToOrder(params) {
|
|
@@ -1015,37 +2269,98 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1015
2269
|
}
|
|
1016
2270
|
return true;
|
|
1017
2271
|
}
|
|
2272
|
+
hasOrderProductLineNote(product) {
|
|
2273
|
+
return typeof (product == null ? void 0 : product.note) === "string" && product.note.trim().length > 0;
|
|
2274
|
+
}
|
|
2275
|
+
/**
|
|
2276
|
+
* 判断商品行是否显式绑定了 booking。
|
|
2277
|
+
*
|
|
2278
|
+
* @example
|
|
2279
|
+
* this.hasLinkedBookingUid({ metadata: { booking_uid: 'booking-1' } });
|
|
2280
|
+
*/
|
|
2281
|
+
hasLinkedBookingUid(product) {
|
|
2282
|
+
var _a;
|
|
2283
|
+
const bookingUid = (product == null ? void 0 : product.booking_uid) ?? ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.booking_uid);
|
|
2284
|
+
return bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "";
|
|
2285
|
+
}
|
|
1018
2286
|
// ─── TempOrder: 商品 CRUD ───
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
2287
|
+
/**
|
|
2288
|
+
* 预约商品加车后的统一收尾:促销、折扣、summary 重算与持久化(批量拆行时只调用一次)。
|
|
2289
|
+
*
|
|
2290
|
+
* @example
|
|
2291
|
+
* await this.finalizeProductOrderMutation(tempOrder);
|
|
2292
|
+
*/
|
|
2293
|
+
async finalizeProductOrderMutation(tempOrder, options) {
|
|
2294
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2295
|
+
if (!(options == null ? void 0 : options.skipEditDiscountConfigRefresh)) {
|
|
2296
|
+
await this.ensureEditDiscountConfigForProductChange(tempOrder);
|
|
2297
|
+
}
|
|
2298
|
+
if (!(options == null ? void 0 : options.skipDiscountRecalculation)) {
|
|
2299
|
+
await this.applyPromotion();
|
|
2300
|
+
}
|
|
2301
|
+
if (!(options == null ? void 0 : options.skipDiscountRecalculation)) {
|
|
2302
|
+
this.applyDiscount();
|
|
2303
|
+
}
|
|
2304
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2305
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2306
|
+
this.persistTempOrder();
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* 向 tempOrder 追加一条商品行(及可选 booking),不触发 summary 重算。
|
|
2310
|
+
* 带 booking 且 num>1 时由 `addProductToOrder` 拆成多次本方法调用(每次 num=1)。
|
|
2311
|
+
*
|
|
2312
|
+
* @example
|
|
2313
|
+
* await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
|
|
2314
|
+
*/
|
|
2315
|
+
async appendProductLineToTempOrder(tempOrder, product, booking) {
|
|
2316
|
+
var _a, _b;
|
|
1022
2317
|
const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
|
|
1023
2318
|
const productToAdd = (linked == null ? void 0 : linked.product) || product;
|
|
1024
2319
|
const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
|
|
1025
|
-
productToAdd
|
|
2320
|
+
(0, import_utils.getProductSkuOptions)(productToAdd),
|
|
1026
2321
|
productToAdd.product_bundle
|
|
1027
2322
|
);
|
|
1028
|
-
const normalizedIncoming = (0,
|
|
2323
|
+
const normalizedIncoming = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2324
|
+
productToAdd,
|
|
2325
|
+
(0, import_utils3.normalizeOrderProduct)(productToAdd)
|
|
2326
|
+
);
|
|
2327
|
+
const incomingBookingUid = productToAdd.booking_uid ?? ((_a = productToAdd.metadata) == null ? void 0 : _a.booking_uid);
|
|
2328
|
+
if (incomingBookingUid !== void 0 && incomingBookingUid !== null && String(incomingBookingUid) !== "") {
|
|
2329
|
+
normalizedIncoming.booking_uid = String(incomingBookingUid);
|
|
2330
|
+
normalizedIncoming.metadata = {
|
|
2331
|
+
...normalizedIncoming.metadata || {},
|
|
2332
|
+
booking_uid: String(incomingBookingUid)
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
normalizedIncoming.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2336
|
+
normalizedIncoming.discount_list
|
|
2337
|
+
);
|
|
1029
2338
|
const hasIncomingGoodPass = this.hasGoodPassDiscount(
|
|
1030
2339
|
normalizedIncoming
|
|
1031
2340
|
);
|
|
1032
|
-
const
|
|
2341
|
+
const hasIncomingProductNote = this.hasOrderProductLineNote(normalizedIncoming);
|
|
2342
|
+
const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
|
|
2343
|
+
const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
|
|
1033
2344
|
const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
|
|
1034
2345
|
if (this.hasGoodPassDiscount(item))
|
|
1035
2346
|
return false;
|
|
2347
|
+
if (this.hasOrderProductLineNote(item))
|
|
2348
|
+
return false;
|
|
2349
|
+
if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
|
|
2350
|
+
return false;
|
|
1036
2351
|
if (item.product_id !== productToAdd.product_id)
|
|
1037
2352
|
return false;
|
|
1038
2353
|
if (item.product_variant_id !== productToAdd.product_variant_id)
|
|
1039
2354
|
return false;
|
|
1040
2355
|
const existedFingerprint2 = (0, import_utils3.buildProductLineFingerprint)(
|
|
1041
|
-
item
|
|
2356
|
+
(0, import_utils.getProductSkuOptions)(item),
|
|
1042
2357
|
item.product_bundle
|
|
1043
2358
|
);
|
|
1044
2359
|
return existedFingerprint2 === incomingFingerprint;
|
|
1045
2360
|
});
|
|
1046
2361
|
const matchedProduct = matchedIndex === -1 ? null : tempOrder.products[matchedIndex];
|
|
1047
2362
|
const existedFingerprint = matchedProduct ? (0, import_utils3.buildProductLineFingerprint)(
|
|
1048
|
-
matchedProduct
|
|
2363
|
+
(0, import_utils.getProductSkuOptions)(matchedProduct),
|
|
1049
2364
|
matchedProduct.product_bundle
|
|
1050
2365
|
) : "";
|
|
1051
2366
|
const shouldMerge = matchedProduct ? await this.shouldMergeProductToOrder({
|
|
@@ -1071,28 +2386,58 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1071
2386
|
booking_uid: linked.bookingUid
|
|
1072
2387
|
};
|
|
1073
2388
|
}
|
|
1074
|
-
tempOrder.products.
|
|
2389
|
+
tempOrder.products = [...tempOrder.products, normalizedIncoming];
|
|
1075
2390
|
} else {
|
|
1076
2391
|
const targetProduct = matchedProduct;
|
|
1077
|
-
const targetUid = (
|
|
1078
|
-
const normalizedProduct = (0,
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
...productToAdd
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
2392
|
+
const targetUid = (_b = targetProduct.metadata) == null ? void 0 : _b.unique_identification_number;
|
|
2393
|
+
const normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2394
|
+
targetProduct,
|
|
2395
|
+
(0, import_utils3.normalizeOrderProduct)({
|
|
2396
|
+
...productToAdd,
|
|
2397
|
+
metadata: {
|
|
2398
|
+
...productToAdd.metadata || {},
|
|
2399
|
+
unique_identification_number: targetUid
|
|
2400
|
+
}
|
|
2401
|
+
})
|
|
2402
|
+
);
|
|
2403
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2404
|
+
normalizedProduct.discount_list
|
|
2405
|
+
);
|
|
2406
|
+
const nextNum = (0, import_utils3.getSafeProductNum)(targetProduct.num + normalizedProduct.num);
|
|
2407
|
+
const targetIsManualProductDiscount = isManualProductDiscountProduct(targetProduct);
|
|
2408
|
+
const nextDiscountList = targetIsManualProductDiscount ? (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2409
|
+
(0, import_manualProductDiscount.syncManualProductDiscountProductNum)(
|
|
2410
|
+
targetProduct.discount_list,
|
|
2411
|
+
nextNum
|
|
2412
|
+
)
|
|
2413
|
+
) : normalizedProduct.discount_list;
|
|
1085
2414
|
tempOrder.products[matchedIndex] = {
|
|
1086
2415
|
...targetProduct,
|
|
1087
2416
|
...normalizedProduct,
|
|
2417
|
+
discount_list: nextDiscountList,
|
|
1088
2418
|
metadata: {
|
|
1089
2419
|
...targetProduct.metadata || {},
|
|
1090
2420
|
...normalizedProduct.metadata || {},
|
|
1091
2421
|
unique_identification_number: targetUid
|
|
1092
2422
|
},
|
|
2423
|
+
product_sku: {
|
|
2424
|
+
...targetProduct.product_sku || { option: [] },
|
|
2425
|
+
...normalizedProduct.product_sku || { option: [] },
|
|
2426
|
+
option: (0, import_utils.getProductSkuOptions)(normalizedProduct)
|
|
2427
|
+
},
|
|
2428
|
+
...targetIsManualProductDiscount ? {
|
|
2429
|
+
selling_price: targetProduct.selling_price,
|
|
2430
|
+
original_price: targetProduct.original_price,
|
|
2431
|
+
payment_price: targetProduct.payment_price,
|
|
2432
|
+
metadata: {
|
|
2433
|
+
...normalizedProduct.metadata || {},
|
|
2434
|
+
...targetProduct.metadata || {},
|
|
2435
|
+
unique_identification_number: targetUid
|
|
2436
|
+
}
|
|
2437
|
+
} : {},
|
|
1093
2438
|
note: targetProduct.note,
|
|
1094
2439
|
order_detail_id: targetProduct.order_detail_id,
|
|
1095
|
-
num:
|
|
2440
|
+
num: nextNum
|
|
1096
2441
|
};
|
|
1097
2442
|
this.captureProductRuntime(
|
|
1098
2443
|
tempOrder,
|
|
@@ -1104,9 +2449,79 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1104
2449
|
if (linked) {
|
|
1105
2450
|
tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
|
|
1106
2451
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* 添加商品行。带 booking 时强制独立行;num>1 时拆成多条 num=1 的 product+booking(对齐 BookingByStep / ticketBooking addService)。
|
|
2455
|
+
*
|
|
2456
|
+
* @example
|
|
2457
|
+
* await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
|
|
2458
|
+
* // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
|
|
2459
|
+
*/
|
|
2460
|
+
async addProductToOrder(product, booking) {
|
|
2461
|
+
const tempOrder = this.ensureTempOrder();
|
|
2462
|
+
if (booking) {
|
|
2463
|
+
const productRecord = product;
|
|
2464
|
+
const splitCount = (0, import_utils3.getSafeProductNum)(
|
|
2465
|
+
productRecord.num ?? productRecord.product_quantity ?? 1
|
|
2466
|
+
);
|
|
2467
|
+
if (splitCount > 1) {
|
|
2468
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
2469
|
+
const singleLine = (0, import_lodash_es.cloneDeep)(productRecord);
|
|
2470
|
+
singleLine.num = 1;
|
|
2471
|
+
delete singleLine.product_quantity;
|
|
2472
|
+
await this.appendProductLineToTempOrder(
|
|
2473
|
+
tempOrder,
|
|
2474
|
+
singleLine,
|
|
2475
|
+
(0, import_lodash_es.cloneDeep)(booking)
|
|
2476
|
+
);
|
|
2477
|
+
}
|
|
2478
|
+
await this.finalizeProductOrderMutation(tempOrder);
|
|
2479
|
+
return tempOrder.products;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
await this.appendProductLineToTempOrder(tempOrder, product, booking);
|
|
2483
|
+
await this.finalizeProductOrderMutation(tempOrder);
|
|
2484
|
+
return tempOrder.products;
|
|
2485
|
+
}
|
|
2486
|
+
/**
|
|
2487
|
+
* 批量添加商品行,所有行追加完成后只触发一次促销、折扣、summary 重算与持久化。
|
|
2488
|
+
*
|
|
2489
|
+
* @example
|
|
2490
|
+
* await order.addProductsToOrder([
|
|
2491
|
+
* { product: { product_id: 1, product_variant_id: 0, num: 1 } },
|
|
2492
|
+
* { product: { product_id: 2, product_variant_id: 0, num: 1 } },
|
|
2493
|
+
* ]);
|
|
2494
|
+
*/
|
|
2495
|
+
async addProductsToOrder(items, options) {
|
|
2496
|
+
const tempOrder = this.ensureTempOrder();
|
|
2497
|
+
if (!Array.isArray(items) || items.length === 0)
|
|
2498
|
+
return tempOrder.products;
|
|
2499
|
+
for (const item of items || []) {
|
|
2500
|
+
const { product, booking } = item;
|
|
2501
|
+
if (!product)
|
|
2502
|
+
continue;
|
|
2503
|
+
if (booking) {
|
|
2504
|
+
const productRecord = product;
|
|
2505
|
+
const splitCount = (0, import_utils3.getSafeProductNum)(
|
|
2506
|
+
productRecord.num ?? productRecord.product_quantity ?? 1
|
|
2507
|
+
);
|
|
2508
|
+
if (splitCount > 1) {
|
|
2509
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
2510
|
+
const singleLine = (0, import_lodash_es.cloneDeep)(productRecord);
|
|
2511
|
+
singleLine.num = 1;
|
|
2512
|
+
delete singleLine.product_quantity;
|
|
2513
|
+
await this.appendProductLineToTempOrder(
|
|
2514
|
+
tempOrder,
|
|
2515
|
+
singleLine,
|
|
2516
|
+
(0, import_lodash_es.cloneDeep)(booking)
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
continue;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
await this.appendProductLineToTempOrder(tempOrder, product, booking);
|
|
2523
|
+
}
|
|
2524
|
+
await this.finalizeProductOrderMutation(tempOrder, options);
|
|
1110
2525
|
return tempOrder.products;
|
|
1111
2526
|
}
|
|
1112
2527
|
hasGoodPassDiscount(product) {
|
|
@@ -1127,15 +2542,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1127
2542
|
(item) => (item == null ? void 0 : item.type) === "good_pass" || (item == null ? void 0 : item.tag) === "good_pass"
|
|
1128
2543
|
);
|
|
1129
2544
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
2545
|
+
getBundleRuntimeIdentity(bundle) {
|
|
2546
|
+
if (!bundle || typeof bundle !== "object")
|
|
2547
|
+
return "";
|
|
2548
|
+
return [
|
|
2549
|
+
bundle.bundle_id ?? bundle.id ?? "",
|
|
2550
|
+
bundle.bundle_group_id ?? bundle.group_id ?? "",
|
|
2551
|
+
bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? "",
|
|
2552
|
+
bundle.bundle_variant_id ?? bundle.product_variant_id ?? 0
|
|
2553
|
+
].join("|");
|
|
2554
|
+
}
|
|
2555
|
+
preservePersistedBundlePriceFields(previousBundles, nextBundles) {
|
|
2556
|
+
if (!Array.isArray(nextBundles))
|
|
2557
|
+
return nextBundles;
|
|
2558
|
+
if (!Array.isArray(previousBundles) || previousBundles.length === 0)
|
|
2559
|
+
return nextBundles;
|
|
2560
|
+
const previousByIdentity = /* @__PURE__ */ new Map();
|
|
2561
|
+
previousBundles.forEach((bundle) => {
|
|
2562
|
+
const identity = this.getBundleRuntimeIdentity(bundle);
|
|
2563
|
+
if (identity)
|
|
2564
|
+
previousByIdentity.set(identity, bundle);
|
|
2565
|
+
});
|
|
2566
|
+
return nextBundles.map((bundle, index) => {
|
|
2567
|
+
if (!bundle || typeof bundle !== "object")
|
|
2568
|
+
return bundle;
|
|
2569
|
+
const previous = previousByIdentity.get(this.getBundleRuntimeIdentity(bundle)) || previousBundles[index];
|
|
2570
|
+
if (!previous || typeof previous !== "object")
|
|
2571
|
+
return bundle;
|
|
2572
|
+
return {
|
|
2573
|
+
...bundle,
|
|
2574
|
+
price: previous.price,
|
|
2575
|
+
custom_price: previous.custom_price,
|
|
2576
|
+
bundle_payment_price: previous.bundle_payment_price,
|
|
2577
|
+
bundle_selling_price: previous.bundle_selling_price,
|
|
2578
|
+
original_price: previous.original_price,
|
|
2579
|
+
product_price: previous.product_price
|
|
2580
|
+
};
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
async updateOrderProduct(params) {
|
|
2584
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
1132
2585
|
const {
|
|
1133
2586
|
product_id,
|
|
1134
2587
|
product_variant_id,
|
|
1135
2588
|
updates,
|
|
1136
2589
|
unique_identification_number,
|
|
1137
|
-
|
|
1138
|
-
|
|
2590
|
+
identity_key,
|
|
2591
|
+
product_sku,
|
|
2592
|
+
product_bundle,
|
|
2593
|
+
booking
|
|
1139
2594
|
} = params;
|
|
1140
2595
|
const tempOrder = this.ensureTempOrder();
|
|
1141
2596
|
const identityLookup = {
|
|
@@ -1144,12 +2599,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1144
2599
|
};
|
|
1145
2600
|
if (unique_identification_number !== void 0) {
|
|
1146
2601
|
identityLookup.unique_identification_number = unique_identification_number;
|
|
2602
|
+
if (identity_key === void 0) {
|
|
2603
|
+
identityLookup.identity_key = unique_identification_number;
|
|
2604
|
+
}
|
|
1147
2605
|
}
|
|
1148
|
-
if (
|
|
1149
|
-
identityLookup.
|
|
2606
|
+
if (identity_key !== void 0) {
|
|
2607
|
+
identityLookup.identity_key = identity_key;
|
|
2608
|
+
}
|
|
2609
|
+
if (product_sku !== void 0)
|
|
2610
|
+
identityLookup.product_sku = product_sku;
|
|
1150
2611
|
if (product_bundle !== void 0)
|
|
1151
2612
|
identityLookup.product_bundle = product_bundle;
|
|
1152
|
-
|
|
2613
|
+
let productIndex = -1;
|
|
2614
|
+
if (unique_identification_number !== void 0) {
|
|
2615
|
+
const targetUid = String(unique_identification_number);
|
|
2616
|
+
productIndex = tempOrder.products.findIndex((item) => {
|
|
2617
|
+
var _a2;
|
|
2618
|
+
return String(
|
|
2619
|
+
((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
|
|
2620
|
+
) === targetUid;
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
if (productIndex === -1) {
|
|
2624
|
+
productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
|
|
2625
|
+
}
|
|
1153
2626
|
if (productIndex === -1) {
|
|
1154
2627
|
throw new Error("[Order] 目标商品不存在,无法更新");
|
|
1155
2628
|
}
|
|
@@ -1163,12 +2636,49 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1163
2636
|
...targetProduct.metadata || {},
|
|
1164
2637
|
...(updates == null ? void 0 : updates.metadata) || {},
|
|
1165
2638
|
unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
|
|
2639
|
+
},
|
|
2640
|
+
product_sku: {
|
|
2641
|
+
...targetProduct.product_sku || { option: [] },
|
|
2642
|
+
...(updates == null ? void 0 : updates.product_sku) && typeof updates.product_sku === "object" ? updates.product_sku : {},
|
|
2643
|
+
option: Array.isArray((_b = updates == null ? void 0 : updates.product_sku) == null ? void 0 : _b.option) ? updates.product_sku.option : (0, import_utils.getProductSkuOptions)(targetProduct)
|
|
1166
2644
|
}
|
|
1167
2645
|
};
|
|
1168
2646
|
nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
|
|
1169
2647
|
const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
|
|
1170
|
-
const callerUpdatesMainMeta = ((
|
|
1171
|
-
|
|
2648
|
+
const callerUpdatesMainMeta = ((_c = updates == null ? void 0 : updates.metadata) == null ? void 0 : _c.main_product_selling_price) !== void 0 || ((_d = updates == null ? void 0 : updates.metadata) == null ? void 0 : _d.main_product_original_price) !== void 0 || ((_e = updates == null ? void 0 : updates.metadata) == null ? void 0 : _e.source_product_price) !== void 0;
|
|
2649
|
+
const isPersistedOrderLine = targetProduct.order_detail_id !== void 0 && targetProduct.order_detail_id !== null;
|
|
2650
|
+
const callerChangesDiscountList = Array.isArray(updates == null ? void 0 : updates.discount_list) && updates.discount_list.length > 0 && !isSameDiscountList(updates.discount_list, targetProduct.discount_list);
|
|
2651
|
+
const callerUpdatesManualPrice = ((_f = updates == null ? void 0 : updates.metadata) == null ? void 0 : _f.price_override) !== void 0 || ((_g = updates == null ? void 0 : updates.metadata) == null ? void 0 : _g.is_manual_discount) !== void 0 || ((_h = updates == null ? void 0 : updates.metadata) == null ? void 0 : _h.product_discount_reason) !== void 0 || callerChangesDiscountList;
|
|
2652
|
+
const callerAllowsBookingReprice = (() => {
|
|
2653
|
+
if (params.allow_booking_reprice !== true || !booking || !callerUpdatesTopPrice || !callerUpdatesMainMeta) {
|
|
2654
|
+
return false;
|
|
2655
|
+
}
|
|
2656
|
+
const hasChangedPrice = (nextValue, currentValue) => {
|
|
2657
|
+
if (nextValue === void 0 || nextValue === null || nextValue === "") {
|
|
2658
|
+
return false;
|
|
2659
|
+
}
|
|
2660
|
+
return !new import_decimal.default(Number(nextValue) || 0).equals(
|
|
2661
|
+
new import_decimal.default(Number(currentValue) || 0)
|
|
2662
|
+
);
|
|
2663
|
+
};
|
|
2664
|
+
return hasChangedPrice(updates.selling_price, targetProduct.selling_price) || hasChangedPrice(updates.original_price, targetProduct.original_price);
|
|
2665
|
+
})();
|
|
2666
|
+
if (isPersistedOrderLine && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
|
|
2667
|
+
nextProduct.selling_price = targetProduct.selling_price;
|
|
2668
|
+
nextProduct.original_price = targetProduct.original_price;
|
|
2669
|
+
nextProduct.payment_price = targetProduct.payment_price;
|
|
2670
|
+
nextProduct.metadata = {
|
|
2671
|
+
...nextProduct.metadata || {},
|
|
2672
|
+
source_product_price: (_i = targetProduct.metadata) == null ? void 0 : _i.source_product_price,
|
|
2673
|
+
main_product_selling_price: (_j = targetProduct.metadata) == null ? void 0 : _j.main_product_selling_price,
|
|
2674
|
+
main_product_original_price: (_k = targetProduct.metadata) == null ? void 0 : _k.main_product_original_price,
|
|
2675
|
+
price_schema_version: ((_l = targetProduct.metadata) == null ? void 0 : _l.price_schema_version) ?? 2
|
|
2676
|
+
};
|
|
2677
|
+
nextProduct.product_bundle = this.preservePersistedBundlePriceFields(
|
|
2678
|
+
targetProduct.product_bundle,
|
|
2679
|
+
nextProduct.product_bundle
|
|
2680
|
+
);
|
|
2681
|
+
} else if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
|
|
1172
2682
|
const existedMeta = nextProduct.metadata || {};
|
|
1173
2683
|
nextProduct.metadata = { ...existedMeta };
|
|
1174
2684
|
delete nextProduct.metadata.source_product_price;
|
|
@@ -1176,39 +2686,280 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1176
2686
|
delete nextProduct.metadata.main_product_original_price;
|
|
1177
2687
|
delete nextProduct.metadata.price_schema_version;
|
|
1178
2688
|
}
|
|
1179
|
-
|
|
2689
|
+
let normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2690
|
+
nextProduct,
|
|
2691
|
+
(0, import_utils3.normalizeOrderProduct)(nextProduct)
|
|
2692
|
+
);
|
|
2693
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2694
|
+
normalizedProduct.discount_list
|
|
2695
|
+
);
|
|
2696
|
+
const preservedBookingUid = nextProduct.booking_uid || ((_m = nextProduct.metadata) == null ? void 0 : _m.booking_uid) || targetProduct.booking_uid || ((_n = targetProduct.metadata) == null ? void 0 : _n.booking_uid);
|
|
2697
|
+
if (!booking && preservedBookingUid) {
|
|
2698
|
+
normalizedProduct.booking_uid = preservedBookingUid;
|
|
2699
|
+
normalizedProduct.metadata = {
|
|
2700
|
+
...normalizedProduct.metadata || {},
|
|
2701
|
+
booking_uid: preservedBookingUid
|
|
2702
|
+
};
|
|
2703
|
+
}
|
|
2704
|
+
if (booking) {
|
|
2705
|
+
const productUid = String(
|
|
2706
|
+
((_o = normalizedProduct.metadata) == null ? void 0 : _o.unique_identification_number) || ((_p = targetProduct.metadata) == null ? void 0 : _p.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
|
|
2707
|
+
);
|
|
2708
|
+
normalizedProduct.metadata = {
|
|
2709
|
+
...normalizedProduct.metadata || {},
|
|
2710
|
+
unique_identification_number: productUid
|
|
2711
|
+
};
|
|
2712
|
+
const linked = this.createLinkedProductAndBooking({
|
|
2713
|
+
product: {
|
|
2714
|
+
...normalizedProduct,
|
|
2715
|
+
unique_identification_number: productUid
|
|
2716
|
+
},
|
|
2717
|
+
booking
|
|
2718
|
+
});
|
|
2719
|
+
this.removeLinkedBookingsForProduct(tempOrder, targetProduct);
|
|
2720
|
+
normalizedProduct = {
|
|
2721
|
+
...normalizedProduct,
|
|
2722
|
+
booking_uid: linked.bookingUid,
|
|
2723
|
+
metadata: {
|
|
2724
|
+
...normalizedProduct.metadata || {},
|
|
2725
|
+
booking_uid: linked.bookingUid,
|
|
2726
|
+
unique_identification_number: productUid
|
|
2727
|
+
}
|
|
2728
|
+
};
|
|
2729
|
+
tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
|
|
2730
|
+
}
|
|
2731
|
+
tempOrder.products[productIndex] = normalizedProduct;
|
|
2732
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
1180
2733
|
this.captureProductRuntime(
|
|
1181
2734
|
tempOrder,
|
|
1182
2735
|
updates,
|
|
1183
2736
|
tempOrder.products[productIndex],
|
|
1184
|
-
(
|
|
2737
|
+
(_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
|
|
1185
2738
|
);
|
|
2739
|
+
await this.applyPromotion();
|
|
1186
2740
|
this.applyDiscount();
|
|
2741
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1187
2742
|
await this.recalculateSummary({ createIfMissing: true });
|
|
1188
2743
|
this.persistTempOrder();
|
|
1189
2744
|
return tempOrder.products;
|
|
1190
2745
|
}
|
|
1191
|
-
async
|
|
2746
|
+
async updateOrderProductQuantity(params) {
|
|
2747
|
+
var _a;
|
|
2748
|
+
const {
|
|
2749
|
+
product_id,
|
|
2750
|
+
product_variant_id,
|
|
2751
|
+
num,
|
|
2752
|
+
unique_identification_number,
|
|
2753
|
+
identity_key,
|
|
2754
|
+
product_sku,
|
|
2755
|
+
product_bundle
|
|
2756
|
+
} = params;
|
|
2757
|
+
const tempOrder = this.ensureTempOrder();
|
|
2758
|
+
const identityLookup = {
|
|
2759
|
+
product_id,
|
|
2760
|
+
product_variant_id
|
|
2761
|
+
};
|
|
2762
|
+
if (unique_identification_number !== void 0) {
|
|
2763
|
+
identityLookup.unique_identification_number = unique_identification_number;
|
|
2764
|
+
if (identity_key === void 0) {
|
|
2765
|
+
identityLookup.identity_key = unique_identification_number;
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
if (identity_key !== void 0)
|
|
2769
|
+
identityLookup.identity_key = identity_key;
|
|
2770
|
+
if (product_sku !== void 0)
|
|
2771
|
+
identityLookup.product_sku = product_sku;
|
|
2772
|
+
if (product_bundle !== void 0)
|
|
2773
|
+
identityLookup.product_bundle = product_bundle;
|
|
2774
|
+
let productIndex = -1;
|
|
2775
|
+
if (unique_identification_number !== void 0) {
|
|
2776
|
+
const targetUid = String(unique_identification_number);
|
|
2777
|
+
productIndex = tempOrder.products.findIndex((item) => {
|
|
2778
|
+
var _a2;
|
|
2779
|
+
return String(
|
|
2780
|
+
((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
|
|
2781
|
+
) === targetUid;
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
if (productIndex === -1) {
|
|
2785
|
+
productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
|
|
2786
|
+
}
|
|
2787
|
+
if (productIndex === -1) {
|
|
2788
|
+
throw new Error("[Order] 目标商品不存在,无法更新数量");
|
|
2789
|
+
}
|
|
2790
|
+
const targetProduct = tempOrder.products[productIndex];
|
|
2791
|
+
const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
|
|
2792
|
+
...targetProduct,
|
|
2793
|
+
num: (0, import_utils3.getSafeProductNum)(num),
|
|
2794
|
+
metadata: {
|
|
2795
|
+
...targetProduct.metadata || {},
|
|
2796
|
+
unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2800
|
+
normalizedProduct.discount_list
|
|
2801
|
+
);
|
|
2802
|
+
tempOrder.products[productIndex] = normalizedProduct;
|
|
2803
|
+
await this.applyPromotion();
|
|
2804
|
+
this.applyDiscount();
|
|
2805
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2806
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2807
|
+
this.persistTempOrder();
|
|
2808
|
+
return tempOrder.products;
|
|
2809
|
+
}
|
|
2810
|
+
updateOrderBooking(params) {
|
|
2811
|
+
const { unique_identification_number, updates } = params;
|
|
1192
2812
|
const tempOrder = this.ensureTempOrder();
|
|
1193
|
-
|
|
1194
|
-
|
|
2813
|
+
const bookingUid = String(unique_identification_number || "");
|
|
2814
|
+
const bookingIndex = this.findBookingIndexByUniqueIdentificationNumber(
|
|
2815
|
+
tempOrder,
|
|
2816
|
+
bookingUid
|
|
1195
2817
|
);
|
|
2818
|
+
if (!bookingUid || bookingIndex === -1) {
|
|
2819
|
+
throw new Error("[Order] 目标 booking 不存在,无法更新");
|
|
2820
|
+
}
|
|
2821
|
+
const targetBooking = tempOrder.bookings[bookingIndex] || {};
|
|
2822
|
+
const nextBooking = {
|
|
2823
|
+
...targetBooking,
|
|
2824
|
+
...updates,
|
|
2825
|
+
metadata: {
|
|
2826
|
+
...targetBooking.metadata || {},
|
|
2827
|
+
...updates.metadata || {},
|
|
2828
|
+
unique_identification_number: bookingUid
|
|
2829
|
+
}
|
|
2830
|
+
};
|
|
2831
|
+
this.syncBookingMetadataHolder(nextBooking, nextBooking.metadata);
|
|
2832
|
+
nextBooking.is_all = (0, import_utils.normalizeBookingIsAll)(nextBooking);
|
|
2833
|
+
nextBooking.sub_type = (0, import_utils.normalizeBookingSubType)(nextBooking);
|
|
2834
|
+
tempOrder.bookings[bookingIndex] = nextBooking;
|
|
2835
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2836
|
+
this.persistTempOrder();
|
|
2837
|
+
return tempOrder.bookings;
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* 商品行写路径收尾:促销 → 折扣 → 清洗 → summary → 持久化。
|
|
2841
|
+
* 批量删除等多行变更场景只应调用一次,避免 N 次 applyPromotion。
|
|
2842
|
+
*
|
|
2843
|
+
* @example
|
|
2844
|
+
* await this.finalizeAfterProductsMutation(tempOrder);
|
|
2845
|
+
*/
|
|
2846
|
+
async finalizeAfterProductsMutation(tempOrder) {
|
|
2847
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2848
|
+
await this.applyPromotion();
|
|
1196
2849
|
this.applyDiscount();
|
|
2850
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1197
2851
|
await this.recalculateSummary({ createIfMissing: true });
|
|
1198
2852
|
this.persistTempOrder();
|
|
2853
|
+
}
|
|
2854
|
+
/**
|
|
2855
|
+
* 批量按 identity 删除购物车行,末尾仅一次促销重算。
|
|
2856
|
+
*
|
|
2857
|
+
* @example
|
|
2858
|
+
* await order.removeProductsFromOrder([identityA, identityB]);
|
|
2859
|
+
*/
|
|
2860
|
+
async removeProductsFromOrder(identities) {
|
|
2861
|
+
const tempOrder = this.ensureTempOrder();
|
|
2862
|
+
if (!identities.length) {
|
|
2863
|
+
return tempOrder.products;
|
|
2864
|
+
}
|
|
2865
|
+
const removedProducts = [];
|
|
2866
|
+
tempOrder.products = tempOrder.products.filter((item) => {
|
|
2867
|
+
const shouldRemove = identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
|
|
2868
|
+
if (shouldRemove)
|
|
2869
|
+
removedProducts.push(item);
|
|
2870
|
+
return !shouldRemove;
|
|
2871
|
+
});
|
|
2872
|
+
for (const product of removedProducts) {
|
|
2873
|
+
this.removeLinkedBookingsForProduct(tempOrder, product);
|
|
2874
|
+
}
|
|
2875
|
+
await this.finalizeAfterProductsMutation(tempOrder);
|
|
1199
2876
|
return tempOrder.products;
|
|
1200
2877
|
}
|
|
2878
|
+
async removeProductFromOrder(identity) {
|
|
2879
|
+
return this.removeProductsFromOrder([identity]);
|
|
2880
|
+
}
|
|
2881
|
+
/**
|
|
2882
|
+
* 仅清空购物车行(products / bookings),不重置整单。
|
|
2883
|
+
* 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
|
|
2884
|
+
*/
|
|
2885
|
+
async clearOrderCartLines() {
|
|
2886
|
+
const tempOrder = this.ensureTempOrder();
|
|
2887
|
+
tempOrder.products = [];
|
|
2888
|
+
tempOrder.bookings = [];
|
|
2889
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2890
|
+
if (tempOrder._extend && typeof tempOrder._extend === "object") {
|
|
2891
|
+
tempOrder._extend = {
|
|
2892
|
+
...tempOrder._extend,
|
|
2893
|
+
productsByUid: {}
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
await this.applyPromotion();
|
|
2897
|
+
this.applyDiscount();
|
|
2898
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2899
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2900
|
+
this.persistTempOrder();
|
|
2901
|
+
return tempOrder;
|
|
2902
|
+
}
|
|
1201
2903
|
// ─── TempOrder: 提交 ───
|
|
2904
|
+
buildCurrentSubmitPayloadForLocalPrint(params) {
|
|
2905
|
+
var _a, _b, _c;
|
|
2906
|
+
const tempOrder = this.ensureTempOrder();
|
|
2907
|
+
this.persistTempOrder();
|
|
2908
|
+
const payload = (0, import_utils.buildSubmitPayload)({
|
|
2909
|
+
tempOrder,
|
|
2910
|
+
cacheId: (params == null ? void 0 : params.cacheId) ?? this.cacheId,
|
|
2911
|
+
platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
|
|
2912
|
+
businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
|
|
2913
|
+
channel: params == null ? void 0 : params.channel,
|
|
2914
|
+
type: params == null ? void 0 : params.type,
|
|
2915
|
+
summary: this.store.summary || (0, import_utils.createEmptySummary)(),
|
|
2916
|
+
enhance: (nextPayload) => ({
|
|
2917
|
+
...nextPayload,
|
|
2918
|
+
order_number: tempOrder.order_number ?? nextPayload.order_number ?? null,
|
|
2919
|
+
shop_order_number: tempOrder.shop_order_number ?? nextPayload.shop_order_number ?? null,
|
|
2920
|
+
shop_full_order_number: tempOrder.shop_full_order_number ?? nextPayload.shop_full_order_number ?? null,
|
|
2921
|
+
small_ticket_data_flag: 1
|
|
2922
|
+
})
|
|
2923
|
+
});
|
|
2924
|
+
payload.created_at = void 0;
|
|
2925
|
+
return payload;
|
|
2926
|
+
}
|
|
2927
|
+
async applyLocalPrintOrderNumbers(order) {
|
|
2928
|
+
const tempOrder = this.ensureTempOrder();
|
|
2929
|
+
if (!order || typeof order !== "object")
|
|
2930
|
+
return tempOrder;
|
|
2931
|
+
const shopOrderNumber = order.shop_order_number;
|
|
2932
|
+
const shopFullOrderNumber = order.shop_full_order_number;
|
|
2933
|
+
if (shopOrderNumber !== void 0 && shopOrderNumber !== null && shopOrderNumber !== "") {
|
|
2934
|
+
tempOrder.shop_order_number = String(shopOrderNumber);
|
|
2935
|
+
}
|
|
2936
|
+
if (shopFullOrderNumber !== void 0 && shopFullOrderNumber !== null && shopFullOrderNumber !== "") {
|
|
2937
|
+
tempOrder.shop_full_order_number = String(shopFullOrderNumber);
|
|
2938
|
+
}
|
|
2939
|
+
this.persistTempOrder();
|
|
2940
|
+
await this.saveDraft();
|
|
2941
|
+
return tempOrder;
|
|
2942
|
+
}
|
|
1202
2943
|
/**
|
|
1203
2944
|
* 提交当前 Sales tempOrder。
|
|
1204
2945
|
*
|
|
1205
2946
|
* smallTicketDataFlag 用于 B 端 checkout 小票数据返回。PaymentModal 在支付提交时
|
|
1206
|
-
* 应传 1,确保 /order/sales/checkout 返回打印所需数据。
|
|
2947
|
+
* 应传 1,确保 /shop/order/sales/checkout 返回打印所需数据。
|
|
1207
2948
|
*/
|
|
1208
2949
|
async submitTempOrder(params) {
|
|
1209
|
-
|
|
2950
|
+
return this.runSubmitTempOrder(params);
|
|
2951
|
+
}
|
|
2952
|
+
async submitTempOrderAsync(params) {
|
|
2953
|
+
return this.runSubmitTempOrder({
|
|
2954
|
+
...params,
|
|
2955
|
+
syncMode: true
|
|
2956
|
+
});
|
|
2957
|
+
}
|
|
2958
|
+
async runSubmitTempOrder(params) {
|
|
2959
|
+
var _a, _b, _c, _d, _e;
|
|
1210
2960
|
const tempOrder = this.ensureTempOrder();
|
|
1211
2961
|
this.persistTempOrder();
|
|
2962
|
+
const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1212
2963
|
const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
|
|
1213
2964
|
const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
|
|
1214
2965
|
const hasPaymentStatusOverride = (params == null ? void 0 : params.paymentStatus) !== void 0;
|
|
@@ -1224,26 +2975,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1224
2975
|
...hasPaymentStatusOverride ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
|
|
1225
2976
|
...hasSmallTicketDataFlagOverride ? { small_ticket_data_flag: params == null ? void 0 : params.smallTicketDataFlag } : {}
|
|
1226
2977
|
};
|
|
1227
|
-
|
|
2978
|
+
const enhancedPayload = (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
|
|
2979
|
+
return enhancedPayload;
|
|
1228
2980
|
} : void 0;
|
|
1229
2981
|
const payload = (0, import_utils.buildSubmitPayload)({
|
|
1230
2982
|
tempOrder,
|
|
1231
2983
|
cacheId: effectiveCacheId,
|
|
1232
2984
|
platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
|
|
1233
|
-
businessCode: params == null ? void 0 : params.businessCode,
|
|
2985
|
+
businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
|
|
1234
2986
|
channel: params == null ? void 0 : params.channel,
|
|
1235
2987
|
type: params == null ? void 0 : params.type,
|
|
2988
|
+
summary: latestSummary,
|
|
2989
|
+
request_unique_idempotency_token: params == null ? void 0 : params.request_unique_idempotency_token,
|
|
1236
2990
|
enhance: enhancePayload
|
|
1237
2991
|
});
|
|
2992
|
+
if (params == null ? void 0 : params.syncMode) {
|
|
2993
|
+
payload.sync_mode = true;
|
|
2994
|
+
}
|
|
2995
|
+
if (!payload.created_at) {
|
|
2996
|
+
payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
2997
|
+
}
|
|
1238
2998
|
await this.saveDraft();
|
|
1239
2999
|
let result;
|
|
1240
3000
|
try {
|
|
1241
3001
|
this.logInfo("submitTempOrder calling sales checkout", {
|
|
1242
3002
|
orderId: payload.order_id,
|
|
1243
3003
|
externalSaleNumber: payload.external_sale_number,
|
|
3004
|
+
requestUniqueIdempotencyToken: payload.request_unique_idempotency_token,
|
|
1244
3005
|
paymentStatus: payload.payment_status,
|
|
1245
|
-
paymentsCount: ((
|
|
1246
|
-
smallTicketDataFlag: payload.small_ticket_data_flag
|
|
3006
|
+
paymentsCount: ((_d = payload.payments) == null ? void 0 : _d.length) || 0,
|
|
3007
|
+
smallTicketDataFlag: payload.small_ticket_data_flag,
|
|
3008
|
+
syncMode: payload.sync_mode
|
|
1247
3009
|
});
|
|
1248
3010
|
result = await this.submitSalesOrder({
|
|
1249
3011
|
query: payload
|
|
@@ -1261,7 +3023,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1261
3023
|
orderId: payload.order_id,
|
|
1262
3024
|
externalSaleNumber: payload.external_sale_number,
|
|
1263
3025
|
paymentStatus: payload.payment_status,
|
|
1264
|
-
paymentsCount: ((
|
|
3026
|
+
paymentsCount: ((_e = payload.payments) == null ? void 0 : _e.length) || 0
|
|
1265
3027
|
});
|
|
1266
3028
|
throw error;
|
|
1267
3029
|
}
|
|
@@ -1271,6 +3033,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1271
3033
|
return result;
|
|
1272
3034
|
}
|
|
1273
3035
|
const submittedOrderId = this.extractOrderIdFromSubmitResult(result);
|
|
3036
|
+
this.logInfo("runSubmitTempOrder: 提交成功", {
|
|
3037
|
+
submittedOrderId,
|
|
3038
|
+
result,
|
|
3039
|
+
tempOrder
|
|
3040
|
+
});
|
|
1274
3041
|
if (submittedOrderId !== null && submittedOrderId !== void 0) {
|
|
1275
3042
|
tempOrder.order_id = submittedOrderId;
|
|
1276
3043
|
const resultRecord = result;
|
|
@@ -1278,23 +3045,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1278
3045
|
submittedOrderId,
|
|
1279
3046
|
(resultRecord == null ? void 0 : resultRecord.data) || resultRecord || {}
|
|
1280
3047
|
);
|
|
3048
|
+
} else if (this.isLocalPendingSubmitResult(result)) {
|
|
3049
|
+
this.store.syncState = "local";
|
|
3050
|
+
} else {
|
|
3051
|
+
this.store.syncState = "submitted";
|
|
1281
3052
|
}
|
|
1282
3053
|
return result;
|
|
1283
3054
|
}
|
|
1284
3055
|
async markLocalOrderSynced(orderId, remoteOrder) {
|
|
1285
3056
|
const tempOrder = this.ensureTempOrder();
|
|
1286
3057
|
tempOrder.order_id = orderId;
|
|
3058
|
+
this.applyRemoteOrderNumbersToTempOrder(tempOrder, remoteOrder);
|
|
1287
3059
|
this.store.lastOrderInfo = remoteOrder;
|
|
1288
3060
|
this.store.syncState = "submitted";
|
|
1289
3061
|
this.persistTempOrder();
|
|
1290
3062
|
await this.saveDraft();
|
|
1291
3063
|
}
|
|
3064
|
+
applyRemoteOrderNumbersToTempOrder(tempOrder, remoteOrder) {
|
|
3065
|
+
const applyOrderNumber = (key) => {
|
|
3066
|
+
const value = remoteOrder == null ? void 0 : remoteOrder[key];
|
|
3067
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
3068
|
+
tempOrder[key] = String(value);
|
|
3069
|
+
}
|
|
3070
|
+
};
|
|
3071
|
+
applyOrderNumber("order_number");
|
|
3072
|
+
applyOrderNumber("shop_order_number");
|
|
3073
|
+
applyOrderNumber("shop_full_order_number");
|
|
3074
|
+
}
|
|
1292
3075
|
isSubmitResponseRejected(response) {
|
|
1293
3076
|
const isErrorCode = (response == null ? void 0 : response.code) !== void 0 && response.code !== 200 && response.code !== "200";
|
|
1294
3077
|
const isErrorStatus = (response == null ? void 0 : response.status) === false || typeof (response == null ? void 0 : response.status) === "number" && response.status >= 400;
|
|
1295
3078
|
const isErrorSuccess = (response == null ? void 0 : response.success) === false;
|
|
1296
3079
|
return isErrorCode || isErrorStatus || isErrorSuccess;
|
|
1297
3080
|
}
|
|
3081
|
+
isLocalPendingSubmitResult(response) {
|
|
3082
|
+
const data = (response == null ? void 0 : response.data) && typeof response.data === "object" ? response.data : response;
|
|
3083
|
+
return Number(data == null ? void 0 : data.need_sync) === 1;
|
|
3084
|
+
}
|
|
1298
3085
|
isSubmitErrorResponse(response) {
|
|
1299
3086
|
if (!response || typeof response !== "object")
|
|
1300
3087
|
return false;
|
|
@@ -1322,26 +3109,51 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1322
3109
|
}
|
|
1323
3110
|
});
|
|
1324
3111
|
}
|
|
3112
|
+
generateIdempotencyToken() {
|
|
3113
|
+
const tempOrder = this.ensureTempOrder();
|
|
3114
|
+
const token = this.buildPaymentSyncIdempotencyToken(
|
|
3115
|
+
tempOrder,
|
|
3116
|
+
tempOrder.payments
|
|
3117
|
+
);
|
|
3118
|
+
return `${token}_${Date.now()}`;
|
|
3119
|
+
}
|
|
1325
3120
|
async syncPaymentsToOrder(params) {
|
|
1326
3121
|
const tempOrder = this.ensureTempOrder();
|
|
1327
3122
|
const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
|
|
1328
3123
|
params.payments || []
|
|
1329
3124
|
);
|
|
3125
|
+
const paymentTotal = this.calculatePaymentTotal(mappedPayments);
|
|
3126
|
+
const targetAmount = this.getPaymentTargetAmount();
|
|
3127
|
+
const isFullyPaid = targetAmount.lte(0) ? true : paymentTotal.gte(targetAmount);
|
|
3128
|
+
const paymentStatus = isFullyPaid ? params.paymentStatus || "paid" : "partially_paid";
|
|
1330
3129
|
tempOrder.payments = mappedPayments;
|
|
1331
|
-
|
|
1332
|
-
tempOrder.payment_status = params.paymentStatus;
|
|
3130
|
+
tempOrder.payment_status = paymentStatus;
|
|
1333
3131
|
this.persistTempOrder();
|
|
1334
3132
|
await this.saveDraft();
|
|
1335
|
-
|
|
1336
|
-
const targetAmount = this.getPaymentTargetAmount();
|
|
1337
|
-
const isFullyPaid = targetAmount.lte(0) ? false : paymentTotal.gte(targetAmount);
|
|
1338
|
-
if (!isFullyPaid || !params.submitWhenPaid) {
|
|
3133
|
+
if (!params.submitWhenPaid) {
|
|
1339
3134
|
return { isFullyPaid };
|
|
1340
3135
|
}
|
|
3136
|
+
if (this.store.syncState === "submitting") {
|
|
3137
|
+
return { isFullyPaid };
|
|
3138
|
+
}
|
|
3139
|
+
this.store.syncState = "submitting";
|
|
3140
|
+
const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(
|
|
3141
|
+
tempOrder,
|
|
3142
|
+
mappedPayments
|
|
3143
|
+
);
|
|
1341
3144
|
const submitResult = await this.submitTempOrder({
|
|
1342
3145
|
payments: mappedPayments,
|
|
1343
|
-
paymentStatus
|
|
1344
|
-
smallTicketDataFlag: params.smallTicketDataFlag
|
|
3146
|
+
paymentStatus,
|
|
3147
|
+
smallTicketDataFlag: params.smallTicketDataFlag,
|
|
3148
|
+
businessCode: params.businessCode,
|
|
3149
|
+
channel: params.channel,
|
|
3150
|
+
enhancePayload: (payload) => {
|
|
3151
|
+
const nextPayload = {
|
|
3152
|
+
...payload,
|
|
3153
|
+
request_unique_idempotency_token: paymentSyncIdempotencyToken
|
|
3154
|
+
};
|
|
3155
|
+
return nextPayload;
|
|
3156
|
+
}
|
|
1345
3157
|
});
|
|
1346
3158
|
return { isFullyPaid, submitResult };
|
|
1347
3159
|
}
|
|
@@ -1477,7 +3289,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1477
3289
|
* Checkout 专用:创建订单到后端
|
|
1478
3290
|
*
|
|
1479
3291
|
* 专门为 Checkout 模块设计的订单创建方法,
|
|
1480
|
-
*
|
|
3292
|
+
* 通过 OS Server 调用 checkout 接口创建订单
|
|
1481
3293
|
* 接收已经处理好的订单数据,无需再处理购物车
|
|
1482
3294
|
*
|
|
1483
3295
|
* @param params Checkout 订单参数(已处理的订单数据)
|
|
@@ -1546,7 +3358,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1546
3358
|
orderData.schedule_date = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1547
3359
|
}
|
|
1548
3360
|
console.log("[Order] 调用后端接口创建订单:", {
|
|
1549
|
-
url: "/order/checkout",
|
|
3361
|
+
url: "/shop/order/checkout",
|
|
1550
3362
|
orderType: orderData.type,
|
|
1551
3363
|
platform: orderData.platform,
|
|
1552
3364
|
isDeposit: orderData.is_deposit,
|
|
@@ -1557,7 +3369,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1557
3369
|
paymentsMethods: ((_m = orderData.payments) == null ? void 0 : _m.map((p) => p.code)) || []
|
|
1558
3370
|
});
|
|
1559
3371
|
this.logInfo("Calling backend checkout API", {
|
|
1560
|
-
url: "/order/checkout",
|
|
3372
|
+
url: "/shop/order/checkout",
|
|
1561
3373
|
orderType: orderData.type,
|
|
1562
3374
|
platform: orderData.platform,
|
|
1563
3375
|
isDeposit: orderData.is_deposit,
|
|
@@ -1579,7 +3391,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1579
3391
|
hasOrderId: !!orderData.order_id,
|
|
1580
3392
|
smallTicketDataFlag: orderData.small_ticket_data_flag
|
|
1581
3393
|
});
|
|
1582
|
-
const response = await this.request.post("/order/checkout", orderData
|
|
3394
|
+
const response = await this.request.post("/order/checkout", orderData, {
|
|
3395
|
+
osServer: true,
|
|
3396
|
+
customToast: () => {
|
|
3397
|
+
}
|
|
3398
|
+
});
|
|
1583
3399
|
this.logInfo("Order API called successfully", {
|
|
1584
3400
|
response
|
|
1585
3401
|
});
|
|
@@ -1599,7 +3415,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1599
3415
|
async submitSalesOrder(params) {
|
|
1600
3416
|
const { url, query } = params;
|
|
1601
3417
|
const fetchUrl = url || "/order/sales/checkout";
|
|
1602
|
-
return this.request.post(fetchUrl, query, { customToast: () => {
|
|
3418
|
+
return this.request.post(fetchUrl, query, { osServer: true, customToast: () => {
|
|
1603
3419
|
} });
|
|
1604
3420
|
}
|
|
1605
3421
|
/**
|
|
@@ -1623,13 +3439,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1623
3439
|
emails: params.emails
|
|
1624
3440
|
});
|
|
1625
3441
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
|
|
3442
|
+
async getSalesOrderByLookup(params) {
|
|
3443
|
+
const lookup = params.lookup === void 0 || params.lookup === null ? "" : String(params.lookup).trim();
|
|
3444
|
+
if (!lookup) {
|
|
3445
|
+
throw new Error("加载销售详情需要 lookup");
|
|
3446
|
+
}
|
|
3447
|
+
if (lookup.startsWith("LOCAL_")) {
|
|
3448
|
+
params.forceRemote = false;
|
|
3449
|
+
}
|
|
3450
|
+
const res = await this.request.get(`/order/sales/${encodeURIComponent(lookup)}`, {
|
|
3451
|
+
with: ["products", "bookings", "payments", "customer", "summary", "contacts_info"],
|
|
3452
|
+
...params.forceRemote ? { forceRemote: true } : {}
|
|
3453
|
+
}, { osServer: true });
|
|
1633
3454
|
if (res.code === 200) {
|
|
1634
3455
|
this.store.lastOrderInfo = res.data;
|
|
1635
3456
|
}
|
|
@@ -1642,58 +3463,64 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1642
3463
|
* 例如数组字段、商品行唯一值、价格 metadata、summary 派生状态和 _extend。
|
|
1643
3464
|
*/
|
|
1644
3465
|
async hydrateTempOrderFromRecord(record, options) {
|
|
3466
|
+
var _a, _b, _c;
|
|
1645
3467
|
const raw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
|
|
3468
|
+
const nextTempOrder = this.normalizeTempOrderForRuntime(raw);
|
|
3469
|
+
const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
|
|
3470
|
+
const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
|
|
3471
|
+
this.store.tempOrder = nextTempOrder;
|
|
3472
|
+
this.store.summary = {
|
|
3473
|
+
...(0, import_utils.createEmptySummary)(),
|
|
3474
|
+
...rawSummary,
|
|
3475
|
+
surcharges: summarySurcharges
|
|
1649
3476
|
};
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
"platform",
|
|
1659
|
-
"sales_channel",
|
|
1660
|
-
"order_sales_channel",
|
|
1661
|
-
"vouchers",
|
|
1662
|
-
"status",
|
|
1663
|
-
"payment_status",
|
|
1664
|
-
"shipping_status",
|
|
1665
|
-
"customer_id",
|
|
1666
|
-
"customer_name",
|
|
1667
|
-
"country_calling_code",
|
|
1668
|
-
"phone",
|
|
1669
|
-
"email",
|
|
1670
|
-
"customer",
|
|
1671
|
-
"is_price_include_tax",
|
|
1672
|
-
"tax_title",
|
|
1673
|
-
"tax_country_code",
|
|
1674
|
-
"currency_code",
|
|
1675
|
-
"currency_symbol",
|
|
1676
|
-
"currency_format",
|
|
1677
|
-
"is_deposit",
|
|
1678
|
-
"deposit_amount",
|
|
1679
|
-
"shop_discount",
|
|
1680
|
-
"surcharge_fee",
|
|
1681
|
-
"note",
|
|
1682
|
-
"buzzer",
|
|
1683
|
-
"delivery_type",
|
|
1684
|
-
"table_number",
|
|
1685
|
-
"schedule_date",
|
|
1686
|
-
"created_at",
|
|
1687
|
-
"request_unique_idempotency_token"
|
|
1688
|
-
];
|
|
1689
|
-
TEMP_ORDER_KEYS.forEach((key) => {
|
|
1690
|
-
if (raw[key] !== void 0) {
|
|
1691
|
-
nextTempOrder[key] = raw[key];
|
|
3477
|
+
nextTempOrder._extend = {
|
|
3478
|
+
...nextTempOrder._extend || {},
|
|
3479
|
+
originalSalesSnapshot: {
|
|
3480
|
+
summary: (0, import_lodash_es.cloneDeep)(this.store.summary),
|
|
3481
|
+
products: (0, import_lodash_es.cloneDeep)(nextTempOrder.products || []),
|
|
3482
|
+
payments: (0, import_lodash_es.cloneDeep)(nextTempOrder.payments || []),
|
|
3483
|
+
surcharges: (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []),
|
|
3484
|
+
productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
|
|
1692
3485
|
}
|
|
1693
|
-
}
|
|
3486
|
+
};
|
|
3487
|
+
this.store.lastOrderInfo = raw.lastOrderInfo || raw;
|
|
3488
|
+
const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
|
|
3489
|
+
const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
|
|
3490
|
+
const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
|
|
3491
|
+
if (!shouldSkipEmptyDiscountSync) {
|
|
3492
|
+
await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
|
|
3493
|
+
await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
|
|
3494
|
+
}
|
|
3495
|
+
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
3496
|
+
await this.recalculateSummary({ createIfMissing: false });
|
|
3497
|
+
}
|
|
3498
|
+
this.persistTempOrder();
|
|
3499
|
+
return nextTempOrder;
|
|
3500
|
+
}
|
|
3501
|
+
normalizeTempOrderForRuntime(raw, options) {
|
|
3502
|
+
var _a, _b;
|
|
3503
|
+
const nextTempOrder = {
|
|
3504
|
+
...this.createDefaultTempOrderInstance(),
|
|
3505
|
+
...raw || {}
|
|
3506
|
+
};
|
|
3507
|
+
delete nextTempOrder.summary;
|
|
3508
|
+
delete nextTempOrder.lastOrderInfo;
|
|
3509
|
+
delete nextTempOrder.discount_list;
|
|
3510
|
+
delete nextTempOrder.shop_id;
|
|
3511
|
+
delete nextTempOrder.create_date;
|
|
3512
|
+
delete nextTempOrder.total_amount;
|
|
3513
|
+
delete nextTempOrder.expect_amount;
|
|
3514
|
+
delete nextTempOrder.paid_amount;
|
|
3515
|
+
delete nextTempOrder.shop_note;
|
|
3516
|
+
delete nextTempOrder.start_time;
|
|
3517
|
+
delete nextTempOrder.tax_fee;
|
|
3518
|
+
delete nextTempOrder.total_refund_amount;
|
|
3519
|
+
delete nextTempOrder.holder_id;
|
|
1694
3520
|
nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
|
|
1695
3521
|
nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
|
|
1696
|
-
|
|
3522
|
+
const rawProducts = Array.isArray(raw.products) ? raw.products : [];
|
|
3523
|
+
nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
|
|
1697
3524
|
nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => ({
|
|
1698
3525
|
...b || {},
|
|
1699
3526
|
is_all: (0, import_utils.normalizeBookingIsAll)(b || {}),
|
|
@@ -1701,7 +3528,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1701
3528
|
})) : [];
|
|
1702
3529
|
nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map((p) => ({ ...p || {} })) : [];
|
|
1703
3530
|
nextTempOrder.surcharges = Array.isArray(raw.surcharges) ? raw.surcharges.map((s) => ({ ...s || {} })) : [];
|
|
1704
|
-
nextTempOrder.discount_list = Array.isArray(raw.discount_list) ? raw.discount_list.map((d) => ({ ...d || {} })) : [];
|
|
1705
3531
|
nextTempOrder.relation_forms = Array.isArray(raw.relation_forms) ? raw.relation_forms.map((f) => ({ ...f || {} })) : [];
|
|
1706
3532
|
nextTempOrder.contacts = Array.isArray(raw.contacts) ? raw.contacts.map((c) => ({ ...c || {} })) : [];
|
|
1707
3533
|
nextTempOrder.contacts_info = raw.contacts_info && typeof raw.contacts_info === "object" && !Array.isArray(raw.contacts_info) ? { ...raw.contacts_info } : null;
|
|
@@ -1709,35 +3535,120 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1709
3535
|
...raw._extend,
|
|
1710
3536
|
productsByUid: raw._extend.productsByUid || {}
|
|
1711
3537
|
} : { productsByUid: {} };
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
3538
|
+
const tempOrderExtend = nextTempOrder._extend;
|
|
3539
|
+
const productsByUid = tempOrderExtend.productsByUid || {};
|
|
3540
|
+
for (const [index, product] of nextTempOrder.products.entries()) {
|
|
3541
|
+
const uid = (_a = product.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
3542
|
+
if (!uid)
|
|
3543
|
+
continue;
|
|
3544
|
+
const existed = productsByUid[uid] && typeof productsByUid[uid] === "object" ? productsByUid[uid] : {};
|
|
3545
|
+
const rawProduct = rawProducts[index] && typeof rawProducts[index] === "object" ? rawProducts[index] : product;
|
|
3546
|
+
const origin = existed.origin ?? rawProduct._origin ?? ((_b = rawProduct.metadata) == null ? void 0 : _b.origin) ?? rawProduct;
|
|
3547
|
+
const originSnapshot = (0, import_lodash_es.cloneDeep)(origin);
|
|
3548
|
+
const productOptionString = this.buildHydratedProductOptionString(rawProduct) || this.buildHydratedProductOptionString(product);
|
|
3549
|
+
if (productOptionString && originSnapshot && typeof originSnapshot === "object") {
|
|
3550
|
+
if (originSnapshot.product_option_string === void 0) {
|
|
3551
|
+
originSnapshot.product_option_string = productOptionString;
|
|
3552
|
+
}
|
|
3553
|
+
if (originSnapshot.product_options_stirng === void 0) {
|
|
3554
|
+
originSnapshot.product_options_stirng = productOptionString;
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
productsByUid[uid] = {
|
|
3558
|
+
...existed,
|
|
3559
|
+
origin: originSnapshot
|
|
3560
|
+
};
|
|
1718
3561
|
}
|
|
1719
|
-
|
|
3562
|
+
tempOrderExtend.productsByUid = productsByUid;
|
|
3563
|
+
if ((options == null ? void 0 : options.ensureIdentity) !== false) {
|
|
3564
|
+
this.ensureExternalSaleNumber(nextTempOrder);
|
|
3565
|
+
}
|
|
3566
|
+
nextTempOrder.vouchers = raw.vouchers || [];
|
|
1720
3567
|
return nextTempOrder;
|
|
1721
3568
|
}
|
|
3569
|
+
pickHydratedDisplayText(value) {
|
|
3570
|
+
if (value === void 0 || value === null)
|
|
3571
|
+
return "";
|
|
3572
|
+
if (typeof value === "string")
|
|
3573
|
+
return value;
|
|
3574
|
+
if (typeof value !== "object")
|
|
3575
|
+
return String(value);
|
|
3576
|
+
return value.auto || value.original || value.en || value["zh-CN"] || value["zh-HK"] || "";
|
|
3577
|
+
}
|
|
3578
|
+
formatHydratedNamePair(group, item) {
|
|
3579
|
+
const groupText = this.pickHydratedDisplayText(group);
|
|
3580
|
+
const itemText = this.pickHydratedDisplayText(item);
|
|
3581
|
+
if (groupText && itemText)
|
|
3582
|
+
return `${groupText}:${itemText}`;
|
|
3583
|
+
return groupText || itemText;
|
|
3584
|
+
}
|
|
3585
|
+
buildHydratedProductOptionString(product) {
|
|
3586
|
+
const segments = [];
|
|
3587
|
+
const sku = (product == null ? void 0 : product.product_sku) || {};
|
|
3588
|
+
if (Array.isArray(sku.variant)) {
|
|
3589
|
+
for (const variant of sku.variant) {
|
|
3590
|
+
const segment = this.formatHydratedNamePair(variant == null ? void 0 : variant.group, variant == null ? void 0 : variant.item);
|
|
3591
|
+
if (segment)
|
|
3592
|
+
segments.push(segment);
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
return segments.join(", ");
|
|
3596
|
+
}
|
|
3597
|
+
normalizeHydratedProductOptionItem(optionItem) {
|
|
3598
|
+
const rawNum = (optionItem == null ? void 0 : optionItem.num) ?? (optionItem == null ? void 0 : optionItem.quantity) ?? 1;
|
|
3599
|
+
const parsedNum = Number(rawNum);
|
|
3600
|
+
const rawPrice = (optionItem == null ? void 0 : optionItem.add_price) ?? (optionItem == null ? void 0 : optionItem.price) ?? 0;
|
|
3601
|
+
const parsedPrice = Number(rawPrice);
|
|
3602
|
+
const normalized = {
|
|
3603
|
+
...optionItem,
|
|
3604
|
+
option_group_item_id: optionItem == null ? void 0 : optionItem.option_group_item_id,
|
|
3605
|
+
option_group_id: optionItem == null ? void 0 : optionItem.option_group_id,
|
|
3606
|
+
num: Number.isFinite(parsedNum) && parsedNum > 0 ? parsedNum : 1,
|
|
3607
|
+
add_price: Number.isFinite(parsedPrice) ? parsedPrice : 0
|
|
3608
|
+
};
|
|
3609
|
+
delete normalized.price;
|
|
3610
|
+
if ((optionItem == null ? void 0 : optionItem.name) !== void 0)
|
|
3611
|
+
normalized.name = optionItem.name;
|
|
3612
|
+
if ((optionItem == null ? void 0 : optionItem.group_name) !== void 0)
|
|
3613
|
+
normalized.group_name = optionItem.group_name;
|
|
3614
|
+
if ((optionItem == null ? void 0 : optionItem.id) !== void 0)
|
|
3615
|
+
normalized.id = optionItem.id;
|
|
3616
|
+
return normalized;
|
|
3617
|
+
}
|
|
1722
3618
|
normalizeHydratedOrderProduct(product) {
|
|
1723
3619
|
const row = { ...product || {} };
|
|
1724
3620
|
if (row.num === void 0 && row.product_quantity !== void 0) {
|
|
1725
3621
|
row.num = row.product_quantity;
|
|
1726
3622
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
3623
|
+
const productSku = (0, import_utils.ensureProductSku)(row);
|
|
3624
|
+
row.product_sku = {
|
|
3625
|
+
...productSku,
|
|
3626
|
+
option: (0, import_utils.normalizeProductSkuOptions)(
|
|
3627
|
+
productSku.option.map(
|
|
3628
|
+
(optionItem) => this.normalizeHydratedProductOptionItem(optionItem || {})
|
|
3629
|
+
)
|
|
3630
|
+
)
|
|
3631
|
+
};
|
|
3632
|
+
delete row[`product_${"option"}_item`];
|
|
1729
3633
|
if (!Array.isArray(row.product_bundle))
|
|
1730
3634
|
row.product_bundle = [];
|
|
1731
3635
|
if (!row.metadata || typeof row.metadata !== "object")
|
|
1732
3636
|
row.metadata = {};
|
|
3637
|
+
if (row.booking_uid && !row.metadata.booking_uid) {
|
|
3638
|
+
row.metadata.booking_uid = row.booking_uid;
|
|
3639
|
+
}
|
|
1733
3640
|
const existingIdentity = row.metadata.unique_identification_number || row.unique_identification_number;
|
|
1734
3641
|
if (!existingIdentity) {
|
|
1735
3642
|
row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
|
|
1736
3643
|
}
|
|
1737
3644
|
const normalized = (0, import_utils3.normalizeOrderProduct)(row);
|
|
3645
|
+
normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
3646
|
+
normalized.discount_list
|
|
3647
|
+
);
|
|
1738
3648
|
const result = {
|
|
1739
3649
|
...row,
|
|
1740
3650
|
...normalized,
|
|
3651
|
+
product_sku: normalized.product_sku,
|
|
1741
3652
|
metadata: {
|
|
1742
3653
|
...row.metadata,
|
|
1743
3654
|
...normalized.metadata
|
|
@@ -1745,7 +3656,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1745
3656
|
};
|
|
1746
3657
|
if (result.metadata)
|
|
1747
3658
|
delete result.metadata.price_schema_version;
|
|
1748
|
-
return result;
|
|
3659
|
+
return this.sanitizeOrderProductForTempOrder(result);
|
|
1749
3660
|
}
|
|
1750
3661
|
getLastOrderInfo() {
|
|
1751
3662
|
var _a;
|
|
@@ -1754,8 +3665,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1754
3665
|
async getOrderInfo(order_id) {
|
|
1755
3666
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
1756
3667
|
with: ["products", "bookings"]
|
|
1757
|
-
}, {
|
|
1758
|
-
osServer: true
|
|
1759
3668
|
});
|
|
1760
3669
|
return res;
|
|
1761
3670
|
}
|