@pisell/pisellos 2.2.244 → 2.2.246
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/promotion/evaluator.js +3 -2
- package/dist/model/strategy/adapter/walletPass/utils.js +7 -4
- package/dist/modules/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 +148 -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 +277 -18
- package/dist/modules/Order/index.js +3581 -779
- 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 +1762 -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 +154 -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 +277 -18
- package/lib/modules/Order/index.js +2317 -337
- 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 +887 -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,390 @@ 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
|
+
getManualDepositOverride(tempOrder) {
|
|
1260
|
+
var _a;
|
|
1261
|
+
const override = (_a = tempOrder._extend) == null ? void 0 : _a.manualDepositOverride;
|
|
1262
|
+
if (!override || typeof override !== "object")
|
|
1263
|
+
return null;
|
|
1264
|
+
if (typeof override.amount !== "string")
|
|
1265
|
+
return null;
|
|
1266
|
+
if (typeof override.productStructuralFingerprint !== "string")
|
|
1267
|
+
return null;
|
|
1268
|
+
return override;
|
|
1269
|
+
}
|
|
1270
|
+
setManualDepositOverride(tempOrder, amount) {
|
|
1271
|
+
tempOrder._extend = {
|
|
1272
|
+
...tempOrder._extend || {},
|
|
1273
|
+
manualDepositOverride: {
|
|
1274
|
+
amount,
|
|
1275
|
+
productStructuralFingerprint: this.buildOrderProductsStructuralFingerprint(tempOrder.products)
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
clearManualDepositOverride(tempOrder) {
|
|
1280
|
+
var _a;
|
|
1281
|
+
if (!((_a = tempOrder._extend) == null ? void 0 : _a.manualDepositOverride))
|
|
1282
|
+
return;
|
|
1283
|
+
tempOrder._extend = { ...tempOrder._extend };
|
|
1284
|
+
delete tempOrder._extend.manualDepositOverride;
|
|
1285
|
+
}
|
|
1286
|
+
getOriginalSalesSnapshot(tempOrder) {
|
|
1287
|
+
var _a;
|
|
1288
|
+
const snapshot = (_a = tempOrder._extend) == null ? void 0 : _a.originalSalesSnapshot;
|
|
1289
|
+
if (!snapshot || typeof snapshot !== "object")
|
|
1290
|
+
return null;
|
|
1291
|
+
if (typeof snapshot.productFingerprint !== "string")
|
|
1292
|
+
return null;
|
|
1293
|
+
return snapshot;
|
|
1294
|
+
}
|
|
1295
|
+
isSnapshotPayableAmountUnchanged(tempOrder, snapshot, snapshotSummary) {
|
|
1296
|
+
const currentPaidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1297
|
+
const currentAmountGap = this.calculateSummaryAmountGap({
|
|
1298
|
+
tempOrder,
|
|
1299
|
+
summary: snapshotSummary,
|
|
1300
|
+
orderPaidAmount: currentPaidPaymentSummary.gapPaidAmount
|
|
1301
|
+
});
|
|
1302
|
+
const snapshotPaidPaymentSummary = this.calculatePaidPaymentSummary(
|
|
1303
|
+
Array.isArray(snapshot.payments) ? snapshot.payments : []
|
|
1304
|
+
);
|
|
1305
|
+
const snapshotAmountGap = this.calculateSummaryAmountGap({
|
|
1306
|
+
tempOrder,
|
|
1307
|
+
summary: snapshotSummary,
|
|
1308
|
+
orderPaidAmount: snapshotPaidPaymentSummary.gapPaidAmount
|
|
1309
|
+
});
|
|
1310
|
+
return currentAmountGap === snapshotAmountGap;
|
|
1311
|
+
}
|
|
1312
|
+
restoreOriginalSnapshotIfProductsUnchanged(tempOrder) {
|
|
1313
|
+
const snapshot = this.getOriginalSalesSnapshot(tempOrder);
|
|
1314
|
+
if (!snapshot)
|
|
1315
|
+
return null;
|
|
1316
|
+
const currentFingerprint = this.buildOrderProductsFingerprint(tempOrder.products);
|
|
1317
|
+
if (currentFingerprint !== snapshot.productFingerprint) {
|
|
1318
|
+
const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
|
|
1319
|
+
const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(
|
|
1320
|
+
Array.isArray(snapshot.products) ? snapshot.products : []
|
|
1321
|
+
);
|
|
1322
|
+
if (currentStructuralFingerprint !== snapshotStructuralFingerprint)
|
|
1323
|
+
return null;
|
|
1324
|
+
}
|
|
1325
|
+
const summary = {
|
|
1326
|
+
...(0, import_utils.createEmptySummary)(),
|
|
1327
|
+
...(0, import_lodash_es.cloneDeep)(snapshot.summary || {})
|
|
1328
|
+
};
|
|
1329
|
+
if (!this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary))
|
|
1330
|
+
return null;
|
|
1331
|
+
if (Array.isArray(snapshot.products)) {
|
|
1332
|
+
tempOrder.products = (0, import_lodash_es.cloneDeep)(snapshot.products);
|
|
1333
|
+
}
|
|
1334
|
+
if (Array.isArray(snapshot.surcharges)) {
|
|
1335
|
+
tempOrder.surcharges = (0, import_lodash_es.cloneDeep)(snapshot.surcharges);
|
|
1336
|
+
}
|
|
1337
|
+
tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
|
|
1338
|
+
tempOrder.deposit_amount = summary.deposit_amount || "0.00";
|
|
1339
|
+
tempOrder.is_deposit = summary.deposit_amount !== "0.00" ? 1 : 0;
|
|
1340
|
+
this.store.summary = summary;
|
|
1341
|
+
return summary;
|
|
1342
|
+
}
|
|
1343
|
+
clearPersistedAmountFieldsForFullRecalc(products) {
|
|
1344
|
+
const moneyKeys = [
|
|
1345
|
+
"surcharge_fee",
|
|
1346
|
+
"main_product_attached_bundle_surcharge_fee",
|
|
1347
|
+
"surcharge_rounding_remainder",
|
|
1348
|
+
"main_product_attached_bundle_tax_fee",
|
|
1349
|
+
"tax_fee",
|
|
1350
|
+
"original_tax_fee",
|
|
1351
|
+
"tax_fee_rounding_remainder",
|
|
1352
|
+
"original_tax_fee_rounding_remainder"
|
|
1353
|
+
];
|
|
1354
|
+
const metadataMoneyKeys = [
|
|
1355
|
+
"main_product_attached_bundle_surcharge_fee",
|
|
1356
|
+
"surcharge_rounding_remainder",
|
|
1357
|
+
"main_product_attached_bundle_tax_fee",
|
|
1358
|
+
"tax_fee_rounding_remainder"
|
|
1359
|
+
];
|
|
1360
|
+
for (const product of products || []) {
|
|
1361
|
+
const record = product;
|
|
1362
|
+
for (const key of moneyKeys)
|
|
1363
|
+
delete record[key];
|
|
1364
|
+
if (record.metadata && typeof record.metadata === "object") {
|
|
1365
|
+
record.metadata = { ...record.metadata };
|
|
1366
|
+
for (const key of metadataMoneyKeys)
|
|
1367
|
+
delete record.metadata[key];
|
|
1368
|
+
}
|
|
1369
|
+
for (const bundle of record.product_bundle || []) {
|
|
1370
|
+
for (const key of moneyKeys)
|
|
1371
|
+
delete bundle[key];
|
|
1372
|
+
if (bundle.metadata && typeof bundle.metadata === "object") {
|
|
1373
|
+
bundle.metadata = { ...bundle.metadata };
|
|
1374
|
+
for (const key of metadataMoneyKeys)
|
|
1375
|
+
delete bundle.metadata[key];
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
540
1380
|
getPaymentTargetAmount() {
|
|
541
1381
|
const tempOrder = this.ensureTempOrder();
|
|
542
1382
|
const summary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
)
|
|
547
|
-
|
|
548
|
-
|
|
1383
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1384
|
+
const refundAmount = this.getSummaryRefundAmount(summary);
|
|
1385
|
+
const netPaidAmount = import_decimal.default.max(
|
|
1386
|
+
paidPaymentSummary.gapPaidAmount.minus(refundAmount),
|
|
1387
|
+
0
|
|
1388
|
+
);
|
|
1389
|
+
return this.calculatePaymentTargetAmount(tempOrder, summary, netPaidAmount);
|
|
549
1390
|
}
|
|
550
1391
|
ensureTempOrder() {
|
|
551
1392
|
if (this.store.tempOrder) {
|
|
@@ -559,17 +1400,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
559
1400
|
return newOrder;
|
|
560
1401
|
}
|
|
561
1402
|
restoreOrder() {
|
|
1403
|
+
var _a, _b;
|
|
562
1404
|
const freshTempOrder = this.createDefaultTempOrderInstance();
|
|
563
1405
|
this.ensureExternalSaleNumber(freshTempOrder);
|
|
564
1406
|
this.store.tempOrder = freshTempOrder;
|
|
565
1407
|
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
566
1408
|
this.store.lastOrderInfo = void 0;
|
|
1409
|
+
this.store.syncState = void 0;
|
|
1410
|
+
void ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList([]));
|
|
1411
|
+
void ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList([]));
|
|
567
1412
|
this.persistTempOrder();
|
|
568
1413
|
return freshTempOrder;
|
|
569
1414
|
}
|
|
570
1415
|
getTempOrder() {
|
|
571
1416
|
return this.store.tempOrder;
|
|
572
1417
|
}
|
|
1418
|
+
async replaceTempOrder(tempOrder, options) {
|
|
1419
|
+
if (!(0, import_utils.isTempOrder)(tempOrder)) {
|
|
1420
|
+
throw new Error("无效的 tempOrder 数据");
|
|
1421
|
+
}
|
|
1422
|
+
const nextTempOrder = this.normalizeTempOrderForRuntime(
|
|
1423
|
+
(0, import_lodash_es.cloneDeep)(tempOrder),
|
|
1424
|
+
{ ensureIdentity: false }
|
|
1425
|
+
);
|
|
1426
|
+
this.store.tempOrder = nextTempOrder;
|
|
1427
|
+
if ((options == null ? void 0 : options.recalculateSummary) !== false) {
|
|
1428
|
+
await this.recalculateSummary({ createIfMissing: false });
|
|
1429
|
+
} else {
|
|
1430
|
+
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
1431
|
+
}
|
|
1432
|
+
if ((options == null ? void 0 : options.persist) !== false) {
|
|
1433
|
+
this.persistTempOrder();
|
|
1434
|
+
}
|
|
1435
|
+
if (options == null ? void 0 : options.saveDraft) {
|
|
1436
|
+
await this.saveDraft();
|
|
1437
|
+
}
|
|
1438
|
+
return nextTempOrder;
|
|
1439
|
+
}
|
|
573
1440
|
getOrderIdentity() {
|
|
574
1441
|
var _a;
|
|
575
1442
|
const tempOrder = this.store.tempOrder;
|
|
@@ -605,9 +1472,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
605
1472
|
return null;
|
|
606
1473
|
const summary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
607
1474
|
const depositAmount = tempOrder.deposit_amount || summary.deposit_amount || "0.00";
|
|
608
|
-
const
|
|
609
|
-
const
|
|
610
|
-
|
|
1475
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1476
|
+
const amountGap = this.calculateSummaryAmountGap({
|
|
1477
|
+
tempOrder,
|
|
1478
|
+
summary,
|
|
1479
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1480
|
+
});
|
|
611
1481
|
return {
|
|
612
1482
|
isDeposit: tempOrder.is_deposit === 1 || depositAmount !== "0.00",
|
|
613
1483
|
depositAmount,
|
|
@@ -650,7 +1520,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
650
1520
|
this.ensureExternalSaleNumber(tempOrder);
|
|
651
1521
|
await this.recalculateSummary({ createIfMissing: true });
|
|
652
1522
|
this.persistTempOrder();
|
|
653
|
-
|
|
1523
|
+
if (this.draftPersistEnabled) {
|
|
1524
|
+
await this.saveDraft();
|
|
1525
|
+
}
|
|
654
1526
|
return tempOrder;
|
|
655
1527
|
}
|
|
656
1528
|
getOrderProducts() {
|
|
@@ -664,6 +1536,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
664
1536
|
product.metadata = metadata;
|
|
665
1537
|
return String(uid);
|
|
666
1538
|
}
|
|
1539
|
+
sanitizeOrderProductForTempOrder(product) {
|
|
1540
|
+
if (product.metadata && typeof product.metadata === "object") {
|
|
1541
|
+
delete product.metadata.origin;
|
|
1542
|
+
}
|
|
1543
|
+
return product;
|
|
1544
|
+
}
|
|
1545
|
+
sanitizeTempOrderProducts(tempOrder) {
|
|
1546
|
+
tempOrder.products = (tempOrder.products || []).map(
|
|
1547
|
+
(product) => this.sanitizeOrderProductForTempOrder(product)
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
667
1550
|
ensureExtend(tempOrder) {
|
|
668
1551
|
if (!tempOrder._extend || typeof tempOrder._extend !== "object") {
|
|
669
1552
|
tempOrder._extend = { productsByUid: {} };
|
|
@@ -697,6 +1580,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
697
1580
|
);
|
|
698
1581
|
productMetadata.unique_identification_number = productUid;
|
|
699
1582
|
bookingMetadata.unique_identification_number = bookingUid;
|
|
1583
|
+
this.syncBookingMetadataHolder(params.booking, bookingMetadata);
|
|
700
1584
|
return {
|
|
701
1585
|
productUid,
|
|
702
1586
|
bookingUid,
|
|
@@ -718,44 +1602,266 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
718
1602
|
}
|
|
719
1603
|
};
|
|
720
1604
|
}
|
|
1605
|
+
/**
|
|
1606
|
+
* booking.holder 是提交真源;metadata.holder 作为详情/回显冗余字段同步保存。
|
|
1607
|
+
*
|
|
1608
|
+
* @example
|
|
1609
|
+
* this.syncBookingMetadataHolder(booking, metadata);
|
|
1610
|
+
*/
|
|
1611
|
+
syncBookingMetadataHolder(booking, metadata) {
|
|
1612
|
+
if ((booking == null ? void 0 : booking.holder) !== void 0) {
|
|
1613
|
+
metadata.holder = booking.holder;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* 从单条 booking 的 holder / metadata 中收集 holder form_record。
|
|
1618
|
+
*
|
|
1619
|
+
* @example
|
|
1620
|
+
* const ids = this.collectBookingHolderRecords(booking);
|
|
1621
|
+
*/
|
|
1622
|
+
collectBookingHolderRecords(booking) {
|
|
1623
|
+
var _a;
|
|
1624
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1625
|
+
const source = (holder == null ? void 0 : holder.form_record) ?? ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id);
|
|
1626
|
+
const records = Array.isArray(source) ? source : [source];
|
|
1627
|
+
return records.filter((record) => record !== void 0 && record !== null && record !== "");
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* 按 form_record 顺序读取 booking holder 的主字段名称。
|
|
1631
|
+
*
|
|
1632
|
+
* @example
|
|
1633
|
+
* const names = this.collectBookingHolderNames(booking);
|
|
1634
|
+
*/
|
|
1635
|
+
collectBookingHolderNames(booking) {
|
|
1636
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1637
|
+
const rawName = holder == null ? void 0 : holder.name;
|
|
1638
|
+
if (Array.isArray(rawName)) {
|
|
1639
|
+
return rawName.map((name) => String(name || "").trim());
|
|
1640
|
+
}
|
|
1641
|
+
if (typeof rawName === "string") {
|
|
1642
|
+
return rawName.split(",").map((name) => name.trim());
|
|
1643
|
+
}
|
|
1644
|
+
return [];
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* 按老 ticketBooking `formatHolder` 语义汇总订单顶层 holder。
|
|
1648
|
+
*
|
|
1649
|
+
* @example
|
|
1650
|
+
* const holder = this.buildTempOrderHolderFromBookings(tempOrder);
|
|
1651
|
+
*/
|
|
1652
|
+
buildTempOrderHolderFromBookings(tempOrder) {
|
|
1653
|
+
var _a, _b;
|
|
1654
|
+
const holderRecords = [];
|
|
1655
|
+
const holderNames = [];
|
|
1656
|
+
let baseHolder = null;
|
|
1657
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1658
|
+
for (const booking of tempOrder.bookings || []) {
|
|
1659
|
+
const holder = (booking == null ? void 0 : booking.holder) && typeof booking.holder === "object" ? booking.holder : null;
|
|
1660
|
+
if (!baseHolder && holder) {
|
|
1661
|
+
baseHolder = holder;
|
|
1662
|
+
}
|
|
1663
|
+
const records = this.collectBookingHolderRecords(booking);
|
|
1664
|
+
const names = this.collectBookingHolderNames(booking);
|
|
1665
|
+
for (const [index, record] of records.entries()) {
|
|
1666
|
+
const key = String(record);
|
|
1667
|
+
if (seen.has(key))
|
|
1668
|
+
continue;
|
|
1669
|
+
seen.add(key);
|
|
1670
|
+
holderRecords.push(record);
|
|
1671
|
+
if (names[index]) {
|
|
1672
|
+
holderNames.push(names[index]);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
if (!holderRecords.length) {
|
|
1677
|
+
return null;
|
|
1678
|
+
}
|
|
1679
|
+
const nextHolder = {
|
|
1680
|
+
customer_id: (baseHolder == null ? void 0 : baseHolder.customer_id) ?? tempOrder.customer_id,
|
|
1681
|
+
form_id: (baseHolder == null ? void 0 : baseHolder.form_id) ?? ((_a = tempOrder.holder) == null ? void 0 : _a.form_id) ?? 0,
|
|
1682
|
+
form_record: holderRecords
|
|
1683
|
+
};
|
|
1684
|
+
if (holderNames.length) {
|
|
1685
|
+
nextHolder.name = holderNames.join(",");
|
|
1686
|
+
}
|
|
1687
|
+
if ((baseHolder == null ? void 0 : baseHolder.is_source_shop) || ((_b = this.otherParams) == null ? void 0 : _b.isFranchisee)) {
|
|
1688
|
+
nextHolder.is_source_shop = 1;
|
|
1689
|
+
}
|
|
1690
|
+
return nextHolder;
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* 将 booking 级 holder 汇总到 tempOrder 顶层 holder。
|
|
1694
|
+
*
|
|
1695
|
+
* @example
|
|
1696
|
+
* this.syncTempOrderHolderFromBookings(tempOrder);
|
|
1697
|
+
*/
|
|
1698
|
+
syncTempOrderHolderFromBookings(tempOrder) {
|
|
1699
|
+
const bookings = tempOrder.bookings || [];
|
|
1700
|
+
const hasHolderSource = bookings.some((booking) => {
|
|
1701
|
+
var _a;
|
|
1702
|
+
return (booking == null ? void 0 : booking.holder) !== void 0 || ((_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.holder_id) !== void 0;
|
|
1703
|
+
});
|
|
1704
|
+
const nextHolder = this.buildTempOrderHolderFromBookings(tempOrder);
|
|
1705
|
+
if (nextHolder || hasHolderSource || bookings.length === 0) {
|
|
1706
|
+
tempOrder.holder = nextHolder;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
getBookingUniqueIdentificationNumber(booking) {
|
|
1710
|
+
var _a;
|
|
1711
|
+
const uid = (_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
1712
|
+
if (uid === void 0 || uid === null || uid === "")
|
|
1713
|
+
return null;
|
|
1714
|
+
return String(uid);
|
|
1715
|
+
}
|
|
1716
|
+
findBookingIndexByUniqueIdentificationNumber(tempOrder, uniqueIdentificationNumber) {
|
|
1717
|
+
return (tempOrder.bookings || []).findIndex((booking) => {
|
|
1718
|
+
return this.getBookingUniqueIdentificationNumber(booking) === uniqueIdentificationNumber;
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
removeLinkedBookingsForProduct(tempOrder, product) {
|
|
1722
|
+
var _a, _b;
|
|
1723
|
+
const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
|
|
1724
|
+
const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.booking_uid);
|
|
1725
|
+
if (!productUid && !bookingUid)
|
|
1726
|
+
return;
|
|
1727
|
+
tempOrder.bookings = (tempOrder.bookings || []).filter((booking) => {
|
|
1728
|
+
const currentBookingUid = this.getBookingUniqueIdentificationNumber(booking);
|
|
1729
|
+
if (bookingUid && currentBookingUid === String(bookingUid))
|
|
1730
|
+
return false;
|
|
1731
|
+
if (productUid && String((booking == null ? void 0 : booking.product_uid) || "") === String(productUid))
|
|
1732
|
+
return false;
|
|
1733
|
+
return true;
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
721
1736
|
// ─── TempOrder: 金额汇总 ───
|
|
722
1737
|
getSalesSummary() {
|
|
723
1738
|
if (!this.salesSummaryModuleName)
|
|
724
1739
|
return null;
|
|
725
1740
|
return this.core.getModule(this.salesSummaryModuleName);
|
|
726
1741
|
}
|
|
1742
|
+
applyOrderProductsDepositSummary(tempOrder, summary) {
|
|
1743
|
+
var _a;
|
|
1744
|
+
const depositSummary = (0, import_utils.calculateOrderProductsDeposit)(tempOrder.products || [], {
|
|
1745
|
+
productsByUid: (_a = tempOrder._extend) == null ? void 0 : _a.productsByUid
|
|
1746
|
+
});
|
|
1747
|
+
const manualDepositOverride = this.getManualDepositOverride(tempOrder);
|
|
1748
|
+
const currentStructuralFingerprint = manualDepositOverride ? this.buildOrderProductsStructuralFingerprint(tempOrder.products) : "";
|
|
1749
|
+
const shouldUseManualDepositOverride = Boolean(
|
|
1750
|
+
manualDepositOverride && manualDepositOverride.productStructuralFingerprint === currentStructuralFingerprint
|
|
1751
|
+
);
|
|
1752
|
+
if (manualDepositOverride && !shouldUseManualDepositOverride) {
|
|
1753
|
+
this.clearManualDepositOverride(tempOrder);
|
|
1754
|
+
}
|
|
1755
|
+
const depositAmount = shouldUseManualDepositOverride ? manualDepositOverride.amount : depositSummary.totalText;
|
|
1756
|
+
const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
|
|
1757
|
+
const nextSummary = {
|
|
1758
|
+
...summary,
|
|
1759
|
+
deposit_amount: depositAmount,
|
|
1760
|
+
deposit: hasDepositAmount ? {
|
|
1761
|
+
total: depositAmount,
|
|
1762
|
+
deposit_policy_ids: depositSummary.deposit_policy_ids,
|
|
1763
|
+
deposit_policy_data: depositSummary.protocols,
|
|
1764
|
+
hasDeposit: true
|
|
1765
|
+
} : void 0
|
|
1766
|
+
};
|
|
1767
|
+
tempOrder.deposit_amount = depositAmount;
|
|
1768
|
+
tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
|
|
1769
|
+
return nextSummary;
|
|
1770
|
+
}
|
|
727
1771
|
async recalculateSummary(options) {
|
|
728
1772
|
const tempOrder = (options == null ? void 0 : options.createIfMissing) ? this.ensureTempOrder() : this.store.tempOrder;
|
|
729
1773
|
if (!tempOrder)
|
|
730
1774
|
return null;
|
|
1775
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1776
|
+
const snapshotSummary = this.restoreOriginalSnapshotIfProductsUnchanged(tempOrder);
|
|
1777
|
+
if (snapshotSummary)
|
|
1778
|
+
return snapshotSummary;
|
|
1779
|
+
const shouldFullRecalculateFromSnapshot = Boolean(this.getOriginalSalesSnapshot(tempOrder));
|
|
1780
|
+
const summaryProducts = shouldFullRecalculateFromSnapshot ? (0, import_lodash_es.cloneDeep)(tempOrder.products || []) : tempOrder.products;
|
|
1781
|
+
if (shouldFullRecalculateFromSnapshot) {
|
|
1782
|
+
this.clearPersistedAmountFieldsForFullRecalc(summaryProducts || []);
|
|
1783
|
+
}
|
|
731
1784
|
const salesSummary = this.getSalesSummary();
|
|
732
1785
|
const existedSummary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1786
|
+
const totalRefundAmount = existedSummary.total_refund_amount || "0.00";
|
|
733
1787
|
const paidPaymentSummary = this.calculatePaidPaymentSummary(
|
|
734
1788
|
tempOrder.payments || []
|
|
735
1789
|
);
|
|
736
1790
|
if (!salesSummary) {
|
|
737
|
-
const
|
|
1791
|
+
const emptyBaseSummary = {
|
|
738
1792
|
...(0, import_utils.createEmptySummary)(),
|
|
739
|
-
|
|
1793
|
+
...existedSummary,
|
|
1794
|
+
total_refund_amount: totalRefundAmount
|
|
1795
|
+
};
|
|
1796
|
+
const emptySummaryBase = {
|
|
1797
|
+
...emptyBaseSummary,
|
|
740
1798
|
customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
|
|
741
1799
|
order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
|
|
742
|
-
pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
|
|
1800
|
+
pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2),
|
|
1801
|
+
rounding_amount: paidPaymentSummary.roundingAmount.toFixed(2)
|
|
1802
|
+
};
|
|
1803
|
+
const emptySummaryWithDeposit = this.applyOrderProductsDepositSummary(
|
|
1804
|
+
tempOrder,
|
|
1805
|
+
emptySummaryBase
|
|
1806
|
+
);
|
|
1807
|
+
const emptySummary = {
|
|
1808
|
+
...emptySummaryWithDeposit,
|
|
1809
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1810
|
+
tempOrder,
|
|
1811
|
+
summary: emptySummaryWithDeposit,
|
|
1812
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1813
|
+
})
|
|
743
1814
|
};
|
|
744
|
-
this.store.summary = emptySummary;
|
|
745
1815
|
tempOrder.surcharge_fee = emptySummary.surcharge_fee;
|
|
1816
|
+
this.store.summary = emptySummary;
|
|
1817
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1818
|
+
previousSummary: existedSummary,
|
|
1819
|
+
summary: emptySummary
|
|
1820
|
+
});
|
|
746
1821
|
return this.store.summary;
|
|
747
1822
|
}
|
|
748
1823
|
const salesSummaryResult = await salesSummary.getSummary({
|
|
749
|
-
products:
|
|
1824
|
+
products: summaryProducts,
|
|
750
1825
|
isPriceIncludeTax: tempOrder.is_price_include_tax,
|
|
751
1826
|
shopDiscount: tempOrder.shop_discount
|
|
752
1827
|
});
|
|
753
|
-
|
|
1828
|
+
if (shouldFullRecalculateFromSnapshot) {
|
|
1829
|
+
tempOrder.products = summaryProducts;
|
|
1830
|
+
}
|
|
1831
|
+
this.syncSummaryProductMetadata(tempOrder.products || []);
|
|
1832
|
+
const roundingAmount = paidPaymentSummary.roundingAmount;
|
|
1833
|
+
const payServiceChargeAmount = paidPaymentSummary.payServiceChargeAmount;
|
|
1834
|
+
const hasSalesSummaryAmount = salesSummaryResult.expect_amount !== void 0 || salesSummaryResult.total_amount !== void 0;
|
|
1835
|
+
const expectAmount = hasSalesSummaryAmount ? new import_decimal.default(salesSummaryResult.expect_amount ?? salesSummaryResult.total_amount ?? 0) : null;
|
|
1836
|
+
const amountPaymentPatch = hasSalesSummaryAmount || !roundingAmount.eq(0) || !payServiceChargeAmount.eq(0) ? {
|
|
1837
|
+
rounding_amount: roundingAmount.toFixed(2),
|
|
1838
|
+
...expectAmount ? {
|
|
1839
|
+
total_amount: import_decimal.default.max(
|
|
1840
|
+
0,
|
|
1841
|
+
expectAmount.plus(roundingAmount).plus(payServiceChargeAmount)
|
|
1842
|
+
).toFixed(2)
|
|
1843
|
+
} : {}
|
|
1844
|
+
} : {};
|
|
1845
|
+
const normalizedExpectAmountPatch = expectAmount && salesSummaryResult.expect_amount === void 0 ? { expect_amount: expectAmount.toFixed(2) } : {};
|
|
1846
|
+
const summaryForGap = this.applyOrderProductsDepositSummary(tempOrder, {
|
|
754
1847
|
...salesSummaryResult,
|
|
755
|
-
total_refund_amount:
|
|
1848
|
+
total_refund_amount: totalRefundAmount,
|
|
1849
|
+
...amountPaymentPatch,
|
|
1850
|
+
...normalizedExpectAmountPatch
|
|
1851
|
+
});
|
|
1852
|
+
const summary = {
|
|
1853
|
+
...summaryForGap,
|
|
1854
|
+
total_refund_amount: totalRefundAmount,
|
|
756
1855
|
customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
|
|
757
1856
|
order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
|
|
758
|
-
|
|
1857
|
+
...amountPaymentPatch,
|
|
1858
|
+
...normalizedExpectAmountPatch,
|
|
1859
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1860
|
+
tempOrder,
|
|
1861
|
+
summary: summaryForGap,
|
|
1862
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1863
|
+
}),
|
|
1864
|
+
pay_service_charge_amount: payServiceChargeAmount.toFixed(2)
|
|
759
1865
|
};
|
|
760
1866
|
this.store.summary = summary;
|
|
761
1867
|
if (summary.is_price_include_tax !== void 0) {
|
|
@@ -766,8 +1872,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
766
1872
|
}
|
|
767
1873
|
tempOrder.surcharge_fee = summary.surcharge_fee;
|
|
768
1874
|
tempOrder.surcharges = summary.surcharges || [];
|
|
769
|
-
tempOrder
|
|
770
|
-
|
|
1875
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1876
|
+
previousSummary: existedSummary,
|
|
1877
|
+
summary
|
|
1878
|
+
});
|
|
771
1879
|
return this.store.summary;
|
|
772
1880
|
}
|
|
773
1881
|
async getOrderSummary() {
|
|
@@ -777,13 +1885,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
777
1885
|
this.persistTempOrder();
|
|
778
1886
|
return summary;
|
|
779
1887
|
}
|
|
780
|
-
|
|
781
|
-
updateTempOrderNote(note) {
|
|
1888
|
+
updateTempOrderNote(note, sync = false) {
|
|
782
1889
|
const tempOrder = this.ensureTempOrder();
|
|
783
1890
|
tempOrder.note = String(note || "");
|
|
784
1891
|
this.persistTempOrder();
|
|
1892
|
+
if (sync) {
|
|
1893
|
+
const orderId = tempOrder.order_id;
|
|
1894
|
+
if (!orderId)
|
|
1895
|
+
return tempOrder.note;
|
|
1896
|
+
return this.syncTempOrderNoteToRemote(orderId, tempOrder.note);
|
|
1897
|
+
}
|
|
785
1898
|
return tempOrder.note;
|
|
786
1899
|
}
|
|
1900
|
+
async syncTempOrderNoteToRemote(orderId, note) {
|
|
1901
|
+
await this.request.put(`/order/order/${orderId}/note`, { note });
|
|
1902
|
+
return note;
|
|
1903
|
+
}
|
|
787
1904
|
getTempOrderNote() {
|
|
788
1905
|
var _a;
|
|
789
1906
|
return ((_a = this.store.tempOrder) == null ? void 0 : _a.note) || "";
|
|
@@ -795,6 +1912,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
795
1912
|
this.persistTempOrder();
|
|
796
1913
|
return tempOrder.shop_discount;
|
|
797
1914
|
}
|
|
1915
|
+
updateTempOrderDepositAmount(amount) {
|
|
1916
|
+
const tempOrder = this.ensureTempOrder();
|
|
1917
|
+
const depositAmount = this.normalizeDepositAmount(amount);
|
|
1918
|
+
const previousSummary = this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1919
|
+
const summaryWithDeposit = this.applyDepositAmountToSummary(
|
|
1920
|
+
tempOrder,
|
|
1921
|
+
{
|
|
1922
|
+
...(0, import_utils.createEmptySummary)(),
|
|
1923
|
+
...previousSummary
|
|
1924
|
+
},
|
|
1925
|
+
depositAmount
|
|
1926
|
+
);
|
|
1927
|
+
this.setManualDepositOverride(tempOrder, depositAmount);
|
|
1928
|
+
const paidPaymentSummary = this.calculatePaidPaymentSummary(tempOrder.payments || []);
|
|
1929
|
+
const summary = {
|
|
1930
|
+
...summaryWithDeposit,
|
|
1931
|
+
amount_gap: this.calculateSummaryAmountGap({
|
|
1932
|
+
tempOrder,
|
|
1933
|
+
summary: summaryWithDeposit,
|
|
1934
|
+
orderPaidAmount: paidPaymentSummary.gapPaidAmount
|
|
1935
|
+
})
|
|
1936
|
+
};
|
|
1937
|
+
this.store.summary = summary;
|
|
1938
|
+
this.updateTempOrderPaymentStatus(tempOrder, {
|
|
1939
|
+
previousSummary,
|
|
1940
|
+
summary
|
|
1941
|
+
});
|
|
1942
|
+
this.persistTempOrder();
|
|
1943
|
+
return summary;
|
|
1944
|
+
}
|
|
798
1945
|
updateTempOrderBuzzer(buzzer) {
|
|
799
1946
|
const tempOrder = this.ensureTempOrder();
|
|
800
1947
|
tempOrder.buzzer = String(buzzer || "");
|
|
@@ -807,14 +1954,77 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
807
1954
|
this.persistTempOrder();
|
|
808
1955
|
return tempOrder.contacts_info;
|
|
809
1956
|
}
|
|
1957
|
+
buildTempOrderCustomer(params) {
|
|
1958
|
+
if (!params.customerId)
|
|
1959
|
+
return null;
|
|
1960
|
+
const source = params.source ? (0, import_lodash_es.cloneDeep)(params.source) : {};
|
|
1961
|
+
const name = source.name ?? source.display_name ?? source.customerName ?? source.customer_name ?? params.customerName;
|
|
1962
|
+
const customerName = source.customer_name ?? source.customerName ?? source.display_name ?? source.name ?? params.customerName;
|
|
1963
|
+
return {
|
|
1964
|
+
...source,
|
|
1965
|
+
id: source.id ?? params.customerId,
|
|
1966
|
+
customer_id: source.customer_id ?? params.customerId,
|
|
1967
|
+
name: String(name || ""),
|
|
1968
|
+
customer_name: String(customerName || ""),
|
|
1969
|
+
country_calling_code: String(
|
|
1970
|
+
source.country_calling_code ?? source.countryCallingCode ?? params.countryCallingCode
|
|
1971
|
+
),
|
|
1972
|
+
phone: String(source.phone ?? params.phone),
|
|
1973
|
+
email: String(source.email ?? params.email)
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1976
|
+
isCustomerBoundDiscount(discount) {
|
|
1977
|
+
const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
|
|
1978
|
+
return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
|
|
1979
|
+
}
|
|
1980
|
+
clearCustomerBoundDiscounts(tempOrder) {
|
|
1981
|
+
var _a, _b, _c, _d;
|
|
1982
|
+
const filterDiscountList = (discountList) => {
|
|
1983
|
+
if (!Array.isArray(discountList))
|
|
1984
|
+
return [];
|
|
1985
|
+
return discountList.filter((discount) => !this.isCustomerBoundDiscount(discount));
|
|
1986
|
+
};
|
|
1987
|
+
tempOrder.products = (tempOrder.products || []).map((product) => {
|
|
1988
|
+
const nextProduct = {
|
|
1989
|
+
...product,
|
|
1990
|
+
discount_list: filterDiscountList(product.discount_list)
|
|
1991
|
+
};
|
|
1992
|
+
if (Array.isArray(nextProduct.product_bundle)) {
|
|
1993
|
+
nextProduct.product_bundle = nextProduct.product_bundle.map((bundle) => ({
|
|
1994
|
+
...bundle,
|
|
1995
|
+
discount_list: filterDiscountList(bundle.discount_list)
|
|
1996
|
+
}));
|
|
1997
|
+
}
|
|
1998
|
+
return nextProduct;
|
|
1999
|
+
});
|
|
2000
|
+
delete tempOrder.discount_list;
|
|
2001
|
+
const discountModule = this.store.discount;
|
|
2002
|
+
if (!discountModule)
|
|
2003
|
+
return;
|
|
2004
|
+
const currentDiscounts = ((_a = discountModule.getDiscountList) == null ? void 0 : _a.call(discountModule)) || [];
|
|
2005
|
+
const currentOriginalDiscounts = ((_b = discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
|
|
2006
|
+
const nextDiscounts = currentDiscounts.filter((discount) => {
|
|
2007
|
+
if (discount == null ? void 0 : discount.isEditMode)
|
|
2008
|
+
return true;
|
|
2009
|
+
return !this.isCustomerBoundDiscount(discount);
|
|
2010
|
+
});
|
|
2011
|
+
const nextOriginalDiscounts = currentOriginalDiscounts.filter((discount) => {
|
|
2012
|
+
if (discount == null ? void 0 : discount.isEditMode)
|
|
2013
|
+
return true;
|
|
2014
|
+
return !this.isCustomerBoundDiscount(discount);
|
|
2015
|
+
});
|
|
2016
|
+
void ((_c = discountModule.setDiscountList) == null ? void 0 : _c.call(discountModule, nextDiscounts));
|
|
2017
|
+
void ((_d = discountModule.setOriginalDiscountList) == null ? void 0 : _d.call(discountModule, nextOriginalDiscounts));
|
|
2018
|
+
}
|
|
810
2019
|
/**
|
|
811
2020
|
* 更新当前 tempOrder 的客户协议字段。
|
|
812
2021
|
*
|
|
813
|
-
* PaymentModal
|
|
2022
|
+
* PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
|
|
814
2023
|
* 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
|
|
815
2024
|
*/
|
|
816
2025
|
updateTempOrderCustomer(customer) {
|
|
817
2026
|
const tempOrder = this.ensureTempOrder();
|
|
2027
|
+
const previousCustomerId = tempOrder.customer_id ?? null;
|
|
818
2028
|
const customerId = customer.customer_id ?? customer.customerId ?? customer.id ?? null;
|
|
819
2029
|
const customerName = customer.customer_name ?? customer.customerName ?? customer.display_name ?? customer.name ?? "";
|
|
820
2030
|
tempOrder.customer_id = customerId === null || customerId === void 0 || customerId === "" ? null : Number(customerId);
|
|
@@ -824,6 +2034,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
824
2034
|
);
|
|
825
2035
|
tempOrder.phone = String(customer.phone || "");
|
|
826
2036
|
tempOrder.email = String(customer.email || "");
|
|
2037
|
+
tempOrder.customer = this.buildTempOrderCustomer({
|
|
2038
|
+
source: customer,
|
|
2039
|
+
customerId: tempOrder.customer_id,
|
|
2040
|
+
customerName: tempOrder.customer_name,
|
|
2041
|
+
countryCallingCode: tempOrder.country_calling_code,
|
|
2042
|
+
phone: tempOrder.phone,
|
|
2043
|
+
email: tempOrder.email
|
|
2044
|
+
});
|
|
2045
|
+
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
827
2046
|
this.persistTempOrder();
|
|
828
2047
|
return {
|
|
829
2048
|
customerId: tempOrder.customer_id,
|
|
@@ -838,11 +2057,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
838
2057
|
return;
|
|
839
2058
|
}
|
|
840
2059
|
const tempOrder = this.ensureTempOrder();
|
|
2060
|
+
const previousCustomerId = tempOrder.customer_id ?? null;
|
|
841
2061
|
tempOrder.customer_id = patch.customer_id || patch.id || null;
|
|
842
2062
|
tempOrder.customer_name = String(patch.customer_name || "");
|
|
843
2063
|
tempOrder.country_calling_code = String(patch.country_calling_code || "");
|
|
844
2064
|
tempOrder.phone = String(patch.phone || "");
|
|
845
2065
|
tempOrder.email = String(patch.email || "");
|
|
2066
|
+
tempOrder.customer = this.buildTempOrderCustomer({
|
|
2067
|
+
source: snapshot || null,
|
|
2068
|
+
customerId: tempOrder.customer_id,
|
|
2069
|
+
customerName: tempOrder.customer_name,
|
|
2070
|
+
countryCallingCode: tempOrder.country_calling_code,
|
|
2071
|
+
phone: tempOrder.phone,
|
|
2072
|
+
email: tempOrder.email
|
|
2073
|
+
});
|
|
846
2074
|
if (snapshot !== void 0) {
|
|
847
2075
|
const extend = this.ensureExtend(tempOrder);
|
|
848
2076
|
if (snapshot === null)
|
|
@@ -850,12 +2078,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
850
2078
|
else
|
|
851
2079
|
extend.customerSnapshot = (0, import_lodash_es.cloneDeep)(snapshot);
|
|
852
2080
|
}
|
|
2081
|
+
const nextCustomerId = tempOrder.customer_id ?? null;
|
|
2082
|
+
if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
|
|
2083
|
+
(0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
|
|
2084
|
+
this.clearCustomerBoundDiscounts(tempOrder);
|
|
2085
|
+
}
|
|
853
2086
|
this.persistTempOrder();
|
|
854
|
-
this.
|
|
2087
|
+
this.saveDraftInBackground();
|
|
2088
|
+
if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
|
|
2089
|
+
this.emitOrderCustomerChange();
|
|
2090
|
+
}
|
|
855
2091
|
}
|
|
856
2092
|
getOrderCustomer() {
|
|
857
2093
|
const tempOrder = this.store.tempOrder;
|
|
858
|
-
if (!tempOrder || tempOrder.customer_id
|
|
2094
|
+
if (!tempOrder || !tempOrder.customer_id) {
|
|
859
2095
|
return null;
|
|
860
2096
|
}
|
|
861
2097
|
return {
|
|
@@ -873,14 +2109,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
873
2109
|
}
|
|
874
2110
|
clearOrderCustomer() {
|
|
875
2111
|
const tempOrder = this.ensureTempOrder();
|
|
2112
|
+
(0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
|
|
876
2113
|
tempOrder.customer_id = null;
|
|
877
2114
|
tempOrder.customer_name = "";
|
|
878
2115
|
tempOrder.country_calling_code = "";
|
|
879
2116
|
tempOrder.phone = "";
|
|
880
2117
|
tempOrder.email = "";
|
|
2118
|
+
tempOrder.customer = null;
|
|
881
2119
|
if (tempOrder._extend)
|
|
882
2120
|
delete tempOrder._extend.customerSnapshot;
|
|
2121
|
+
this.clearCustomerBoundDiscounts(tempOrder);
|
|
883
2122
|
this.persistTempOrder();
|
|
2123
|
+
this.saveDraftInBackground();
|
|
884
2124
|
this.core.effects.emit(import_types.OrderHooks.OnOrderCustomerChange, null);
|
|
885
2125
|
}
|
|
886
2126
|
emitOrderCustomerChange() {
|
|
@@ -920,10 +2160,28 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
920
2160
|
}
|
|
921
2161
|
/** 追加单个支付项,并立即持久化当前 tempOrder。 */
|
|
922
2162
|
addOrderPayment(payment) {
|
|
2163
|
+
this.logInfo("addOrderPayment", {
|
|
2164
|
+
payment
|
|
2165
|
+
});
|
|
923
2166
|
const tempOrder = this.ensureTempOrder();
|
|
924
|
-
const
|
|
2167
|
+
const orderPaymentType = this.resolveNextOrderPaymentType(tempOrder);
|
|
2168
|
+
const mapped = (0, import_utils.mapPaymentItemsToOrderPayments)([
|
|
2169
|
+
this.normalizePaymentSource(
|
|
2170
|
+
{
|
|
2171
|
+
...payment,
|
|
2172
|
+
type: orderPaymentType,
|
|
2173
|
+
order_payment_type: orderPaymentType
|
|
2174
|
+
},
|
|
2175
|
+
{ defaultPaid: true }
|
|
2176
|
+
)
|
|
2177
|
+
]);
|
|
925
2178
|
tempOrder.payments = [...tempOrder.payments || [], ...mapped];
|
|
926
2179
|
this.persistTempOrder();
|
|
2180
|
+
void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
|
|
2181
|
+
this.logError("recalculate summary after addOrderPayment failed", {
|
|
2182
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2183
|
+
});
|
|
2184
|
+
});
|
|
927
2185
|
return tempOrder.payments;
|
|
928
2186
|
}
|
|
929
2187
|
/**
|
|
@@ -989,14 +2247,48 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
989
2247
|
*/
|
|
990
2248
|
updateVoucherOrderPayments(payments) {
|
|
991
2249
|
const tempOrder = this.ensureTempOrder();
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
|
|
2250
|
+
const isVoucherPayment = (payment) => {
|
|
2251
|
+
return payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0;
|
|
2252
|
+
};
|
|
2253
|
+
const hasSyncedOrderPayment = (payment) => {
|
|
2254
|
+
return payment.order_payment_id !== void 0 && payment.order_payment_id !== null;
|
|
2255
|
+
};
|
|
2256
|
+
const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(
|
|
2257
|
+
payments.map(
|
|
2258
|
+
(payment) => this.normalizePaymentSource(payment, { defaultPaid: true })
|
|
2259
|
+
)
|
|
2260
|
+
).filter((payment) => {
|
|
2261
|
+
return isVoucherPayment(payment);
|
|
2262
|
+
});
|
|
995
2263
|
const nonVoucherPayments = (tempOrder.payments || []).filter((payment) => {
|
|
996
|
-
return
|
|
2264
|
+
return !isVoucherPayment(payment);
|
|
2265
|
+
});
|
|
2266
|
+
const syncedVoucherPayments = (tempOrder.payments || []).filter((payment) => {
|
|
2267
|
+
return isVoucherPayment(payment) && hasSyncedOrderPayment(payment);
|
|
2268
|
+
});
|
|
2269
|
+
const syncedVoucherPaymentIds = new Set(
|
|
2270
|
+
syncedVoucherPayments.map((payment) => String(payment.order_payment_id))
|
|
2271
|
+
);
|
|
2272
|
+
const replaceableVouchers = mappedVouchers.filter((payment) => {
|
|
2273
|
+
if (!hasSyncedOrderPayment(payment))
|
|
2274
|
+
return true;
|
|
2275
|
+
return !syncedVoucherPaymentIds.has(String(payment.order_payment_id));
|
|
997
2276
|
});
|
|
998
|
-
|
|
2277
|
+
const cappedVouchers = this.capVoucherPaymentsByRemainingAmount({
|
|
2278
|
+
vouchers: replaceableVouchers,
|
|
2279
|
+
nonVoucherPayments: [
|
|
2280
|
+
...nonVoucherPayments,
|
|
2281
|
+
...syncedVoucherPayments
|
|
2282
|
+
]
|
|
2283
|
+
});
|
|
2284
|
+
tempOrder.payments = [...nonVoucherPayments, ...syncedVoucherPayments, ...cappedVouchers];
|
|
2285
|
+
this.updateTempOrderPaymentStatus(tempOrder);
|
|
999
2286
|
this.persistTempOrder();
|
|
2287
|
+
void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
|
|
2288
|
+
this.logError("recalculate summary after updateVoucherOrderPayments failed", {
|
|
2289
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2290
|
+
});
|
|
2291
|
+
});
|
|
1000
2292
|
return tempOrder.payments;
|
|
1001
2293
|
}
|
|
1002
2294
|
async shouldMergeProductToOrder(params) {
|
|
@@ -1015,37 +2307,98 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1015
2307
|
}
|
|
1016
2308
|
return true;
|
|
1017
2309
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
2310
|
+
hasOrderProductLineNote(product) {
|
|
2311
|
+
return typeof (product == null ? void 0 : product.note) === "string" && product.note.trim().length > 0;
|
|
2312
|
+
}
|
|
2313
|
+
/**
|
|
2314
|
+
* 判断商品行是否显式绑定了 booking。
|
|
2315
|
+
*
|
|
2316
|
+
* @example
|
|
2317
|
+
* this.hasLinkedBookingUid({ metadata: { booking_uid: 'booking-1' } });
|
|
2318
|
+
*/
|
|
2319
|
+
hasLinkedBookingUid(product) {
|
|
2320
|
+
var _a;
|
|
2321
|
+
const bookingUid = (product == null ? void 0 : product.booking_uid) ?? ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.booking_uid);
|
|
2322
|
+
return bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "";
|
|
2323
|
+
}
|
|
2324
|
+
// ─── TempOrder: 商品 CRUD ───
|
|
2325
|
+
/**
|
|
2326
|
+
* 预约商品加车后的统一收尾:促销、折扣、summary 重算与持久化(批量拆行时只调用一次)。
|
|
2327
|
+
*
|
|
2328
|
+
* @example
|
|
2329
|
+
* await this.finalizeProductOrderMutation(tempOrder);
|
|
2330
|
+
*/
|
|
2331
|
+
async finalizeProductOrderMutation(tempOrder, options) {
|
|
2332
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2333
|
+
if (!(options == null ? void 0 : options.skipEditDiscountConfigRefresh)) {
|
|
2334
|
+
await this.ensureEditDiscountConfigForProductChange(tempOrder);
|
|
2335
|
+
}
|
|
2336
|
+
if (!(options == null ? void 0 : options.skipDiscountRecalculation)) {
|
|
2337
|
+
await this.applyPromotion();
|
|
2338
|
+
}
|
|
2339
|
+
if (!(options == null ? void 0 : options.skipDiscountRecalculation)) {
|
|
2340
|
+
this.applyDiscount();
|
|
2341
|
+
}
|
|
2342
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2343
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2344
|
+
this.persistTempOrder();
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* 向 tempOrder 追加一条商品行(及可选 booking),不触发 summary 重算。
|
|
2348
|
+
* 带 booking 且 num>1 时由 `addProductToOrder` 拆成多次本方法调用(每次 num=1)。
|
|
2349
|
+
*
|
|
2350
|
+
* @example
|
|
2351
|
+
* await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
|
|
2352
|
+
*/
|
|
2353
|
+
async appendProductLineToTempOrder(tempOrder, product, booking) {
|
|
2354
|
+
var _a, _b;
|
|
1022
2355
|
const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
|
|
1023
2356
|
const productToAdd = (linked == null ? void 0 : linked.product) || product;
|
|
1024
2357
|
const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
|
|
1025
|
-
productToAdd
|
|
2358
|
+
(0, import_utils.getProductSkuOptions)(productToAdd),
|
|
1026
2359
|
productToAdd.product_bundle
|
|
1027
2360
|
);
|
|
1028
|
-
const normalizedIncoming = (0,
|
|
2361
|
+
const normalizedIncoming = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2362
|
+
productToAdd,
|
|
2363
|
+
(0, import_utils3.normalizeOrderProduct)(productToAdd)
|
|
2364
|
+
);
|
|
2365
|
+
const incomingBookingUid = productToAdd.booking_uid ?? ((_a = productToAdd.metadata) == null ? void 0 : _a.booking_uid);
|
|
2366
|
+
if (incomingBookingUid !== void 0 && incomingBookingUid !== null && String(incomingBookingUid) !== "") {
|
|
2367
|
+
normalizedIncoming.booking_uid = String(incomingBookingUid);
|
|
2368
|
+
normalizedIncoming.metadata = {
|
|
2369
|
+
...normalizedIncoming.metadata || {},
|
|
2370
|
+
booking_uid: String(incomingBookingUid)
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
normalizedIncoming.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2374
|
+
normalizedIncoming.discount_list
|
|
2375
|
+
);
|
|
1029
2376
|
const hasIncomingGoodPass = this.hasGoodPassDiscount(
|
|
1030
2377
|
normalizedIncoming
|
|
1031
2378
|
);
|
|
1032
|
-
const
|
|
2379
|
+
const hasIncomingProductNote = this.hasOrderProductLineNote(normalizedIncoming);
|
|
2380
|
+
const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
|
|
2381
|
+
const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
|
|
1033
2382
|
const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
|
|
1034
2383
|
if (this.hasGoodPassDiscount(item))
|
|
1035
2384
|
return false;
|
|
2385
|
+
if (this.hasOrderProductLineNote(item))
|
|
2386
|
+
return false;
|
|
2387
|
+
if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
|
|
2388
|
+
return false;
|
|
1036
2389
|
if (item.product_id !== productToAdd.product_id)
|
|
1037
2390
|
return false;
|
|
1038
2391
|
if (item.product_variant_id !== productToAdd.product_variant_id)
|
|
1039
2392
|
return false;
|
|
1040
2393
|
const existedFingerprint2 = (0, import_utils3.buildProductLineFingerprint)(
|
|
1041
|
-
item
|
|
2394
|
+
(0, import_utils.getProductSkuOptions)(item),
|
|
1042
2395
|
item.product_bundle
|
|
1043
2396
|
);
|
|
1044
2397
|
return existedFingerprint2 === incomingFingerprint;
|
|
1045
2398
|
});
|
|
1046
2399
|
const matchedProduct = matchedIndex === -1 ? null : tempOrder.products[matchedIndex];
|
|
1047
2400
|
const existedFingerprint = matchedProduct ? (0, import_utils3.buildProductLineFingerprint)(
|
|
1048
|
-
matchedProduct
|
|
2401
|
+
(0, import_utils.getProductSkuOptions)(matchedProduct),
|
|
1049
2402
|
matchedProduct.product_bundle
|
|
1050
2403
|
) : "";
|
|
1051
2404
|
const shouldMerge = matchedProduct ? await this.shouldMergeProductToOrder({
|
|
@@ -1071,28 +2424,58 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1071
2424
|
booking_uid: linked.bookingUid
|
|
1072
2425
|
};
|
|
1073
2426
|
}
|
|
1074
|
-
tempOrder.products.
|
|
2427
|
+
tempOrder.products = [...tempOrder.products, normalizedIncoming];
|
|
1075
2428
|
} else {
|
|
1076
2429
|
const targetProduct = matchedProduct;
|
|
1077
|
-
const targetUid = (
|
|
1078
|
-
const normalizedProduct = (0,
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
...productToAdd
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
2430
|
+
const targetUid = (_b = targetProduct.metadata) == null ? void 0 : _b.unique_identification_number;
|
|
2431
|
+
const normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2432
|
+
targetProduct,
|
|
2433
|
+
(0, import_utils3.normalizeOrderProduct)({
|
|
2434
|
+
...productToAdd,
|
|
2435
|
+
metadata: {
|
|
2436
|
+
...productToAdd.metadata || {},
|
|
2437
|
+
unique_identification_number: targetUid
|
|
2438
|
+
}
|
|
2439
|
+
})
|
|
2440
|
+
);
|
|
2441
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2442
|
+
normalizedProduct.discount_list
|
|
2443
|
+
);
|
|
2444
|
+
const nextNum = (0, import_utils3.getSafeProductNum)(targetProduct.num + normalizedProduct.num);
|
|
2445
|
+
const targetIsManualProductDiscount = isManualProductDiscountProduct(targetProduct);
|
|
2446
|
+
const nextDiscountList = targetIsManualProductDiscount ? (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2447
|
+
(0, import_manualProductDiscount.syncManualProductDiscountProductNum)(
|
|
2448
|
+
targetProduct.discount_list,
|
|
2449
|
+
nextNum
|
|
2450
|
+
)
|
|
2451
|
+
) : normalizedProduct.discount_list;
|
|
1085
2452
|
tempOrder.products[matchedIndex] = {
|
|
1086
2453
|
...targetProduct,
|
|
1087
2454
|
...normalizedProduct,
|
|
2455
|
+
discount_list: nextDiscountList,
|
|
1088
2456
|
metadata: {
|
|
1089
2457
|
...targetProduct.metadata || {},
|
|
1090
2458
|
...normalizedProduct.metadata || {},
|
|
1091
2459
|
unique_identification_number: targetUid
|
|
1092
2460
|
},
|
|
2461
|
+
product_sku: {
|
|
2462
|
+
...targetProduct.product_sku || { option: [] },
|
|
2463
|
+
...normalizedProduct.product_sku || { option: [] },
|
|
2464
|
+
option: (0, import_utils.getProductSkuOptions)(normalizedProduct)
|
|
2465
|
+
},
|
|
2466
|
+
...targetIsManualProductDiscount ? {
|
|
2467
|
+
selling_price: targetProduct.selling_price,
|
|
2468
|
+
original_price: targetProduct.original_price,
|
|
2469
|
+
payment_price: targetProduct.payment_price,
|
|
2470
|
+
metadata: {
|
|
2471
|
+
...normalizedProduct.metadata || {},
|
|
2472
|
+
...targetProduct.metadata || {},
|
|
2473
|
+
unique_identification_number: targetUid
|
|
2474
|
+
}
|
|
2475
|
+
} : {},
|
|
1093
2476
|
note: targetProduct.note,
|
|
1094
2477
|
order_detail_id: targetProduct.order_detail_id,
|
|
1095
|
-
num:
|
|
2478
|
+
num: nextNum
|
|
1096
2479
|
};
|
|
1097
2480
|
this.captureProductRuntime(
|
|
1098
2481
|
tempOrder,
|
|
@@ -1104,9 +2487,79 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1104
2487
|
if (linked) {
|
|
1105
2488
|
tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
|
|
1106
2489
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
2490
|
+
}
|
|
2491
|
+
/**
|
|
2492
|
+
* 添加商品行。带 booking 时强制独立行;num>1 时拆成多条 num=1 的 product+booking(对齐 BookingByStep / ticketBooking addService)。
|
|
2493
|
+
*
|
|
2494
|
+
* @example
|
|
2495
|
+
* await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
|
|
2496
|
+
* // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
|
|
2497
|
+
*/
|
|
2498
|
+
async addProductToOrder(product, booking) {
|
|
2499
|
+
const tempOrder = this.ensureTempOrder();
|
|
2500
|
+
if (booking) {
|
|
2501
|
+
const productRecord = product;
|
|
2502
|
+
const splitCount = (0, import_utils3.getSafeProductNum)(
|
|
2503
|
+
productRecord.num ?? productRecord.product_quantity ?? 1
|
|
2504
|
+
);
|
|
2505
|
+
if (splitCount > 1) {
|
|
2506
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
2507
|
+
const singleLine = (0, import_lodash_es.cloneDeep)(productRecord);
|
|
2508
|
+
singleLine.num = 1;
|
|
2509
|
+
delete singleLine.product_quantity;
|
|
2510
|
+
await this.appendProductLineToTempOrder(
|
|
2511
|
+
tempOrder,
|
|
2512
|
+
singleLine,
|
|
2513
|
+
(0, import_lodash_es.cloneDeep)(booking)
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2516
|
+
await this.finalizeProductOrderMutation(tempOrder);
|
|
2517
|
+
return tempOrder.products;
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
await this.appendProductLineToTempOrder(tempOrder, product, booking);
|
|
2521
|
+
await this.finalizeProductOrderMutation(tempOrder);
|
|
2522
|
+
return tempOrder.products;
|
|
2523
|
+
}
|
|
2524
|
+
/**
|
|
2525
|
+
* 批量添加商品行,所有行追加完成后只触发一次促销、折扣、summary 重算与持久化。
|
|
2526
|
+
*
|
|
2527
|
+
* @example
|
|
2528
|
+
* await order.addProductsToOrder([
|
|
2529
|
+
* { product: { product_id: 1, product_variant_id: 0, num: 1 } },
|
|
2530
|
+
* { product: { product_id: 2, product_variant_id: 0, num: 1 } },
|
|
2531
|
+
* ]);
|
|
2532
|
+
*/
|
|
2533
|
+
async addProductsToOrder(items, options) {
|
|
2534
|
+
const tempOrder = this.ensureTempOrder();
|
|
2535
|
+
if (!Array.isArray(items) || items.length === 0)
|
|
2536
|
+
return tempOrder.products;
|
|
2537
|
+
for (const item of items || []) {
|
|
2538
|
+
const { product, booking } = item;
|
|
2539
|
+
if (!product)
|
|
2540
|
+
continue;
|
|
2541
|
+
if (booking) {
|
|
2542
|
+
const productRecord = product;
|
|
2543
|
+
const splitCount = (0, import_utils3.getSafeProductNum)(
|
|
2544
|
+
productRecord.num ?? productRecord.product_quantity ?? 1
|
|
2545
|
+
);
|
|
2546
|
+
if (splitCount > 1) {
|
|
2547
|
+
for (let i = 0; i < splitCount; i += 1) {
|
|
2548
|
+
const singleLine = (0, import_lodash_es.cloneDeep)(productRecord);
|
|
2549
|
+
singleLine.num = 1;
|
|
2550
|
+
delete singleLine.product_quantity;
|
|
2551
|
+
await this.appendProductLineToTempOrder(
|
|
2552
|
+
tempOrder,
|
|
2553
|
+
singleLine,
|
|
2554
|
+
(0, import_lodash_es.cloneDeep)(booking)
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2557
|
+
continue;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
await this.appendProductLineToTempOrder(tempOrder, product, booking);
|
|
2561
|
+
}
|
|
2562
|
+
await this.finalizeProductOrderMutation(tempOrder, options);
|
|
1110
2563
|
return tempOrder.products;
|
|
1111
2564
|
}
|
|
1112
2565
|
hasGoodPassDiscount(product) {
|
|
@@ -1127,15 +2580,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1127
2580
|
(item) => (item == null ? void 0 : item.type) === "good_pass" || (item == null ? void 0 : item.tag) === "good_pass"
|
|
1128
2581
|
);
|
|
1129
2582
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
2583
|
+
getBundleRuntimeIdentity(bundle) {
|
|
2584
|
+
if (!bundle || typeof bundle !== "object")
|
|
2585
|
+
return "";
|
|
2586
|
+
return [
|
|
2587
|
+
bundle.bundle_id ?? bundle.id ?? "",
|
|
2588
|
+
bundle.bundle_group_id ?? bundle.group_id ?? "",
|
|
2589
|
+
bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? "",
|
|
2590
|
+
bundle.bundle_variant_id ?? bundle.product_variant_id ?? 0
|
|
2591
|
+
].join("|");
|
|
2592
|
+
}
|
|
2593
|
+
preservePersistedBundlePriceFields(previousBundles, nextBundles) {
|
|
2594
|
+
if (!Array.isArray(nextBundles))
|
|
2595
|
+
return nextBundles;
|
|
2596
|
+
if (!Array.isArray(previousBundles) || previousBundles.length === 0)
|
|
2597
|
+
return nextBundles;
|
|
2598
|
+
const previousByIdentity = /* @__PURE__ */ new Map();
|
|
2599
|
+
previousBundles.forEach((bundle) => {
|
|
2600
|
+
const identity = this.getBundleRuntimeIdentity(bundle);
|
|
2601
|
+
if (identity)
|
|
2602
|
+
previousByIdentity.set(identity, bundle);
|
|
2603
|
+
});
|
|
2604
|
+
return nextBundles.map((bundle, index) => {
|
|
2605
|
+
if (!bundle || typeof bundle !== "object")
|
|
2606
|
+
return bundle;
|
|
2607
|
+
const previous = previousByIdentity.get(this.getBundleRuntimeIdentity(bundle)) || previousBundles[index];
|
|
2608
|
+
if (!previous || typeof previous !== "object")
|
|
2609
|
+
return bundle;
|
|
2610
|
+
return {
|
|
2611
|
+
...bundle,
|
|
2612
|
+
price: previous.price,
|
|
2613
|
+
custom_price: previous.custom_price,
|
|
2614
|
+
bundle_payment_price: previous.bundle_payment_price,
|
|
2615
|
+
bundle_selling_price: previous.bundle_selling_price,
|
|
2616
|
+
original_price: previous.original_price,
|
|
2617
|
+
product_price: previous.product_price
|
|
2618
|
+
};
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
async updateOrderProduct(params) {
|
|
2622
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
1132
2623
|
const {
|
|
1133
2624
|
product_id,
|
|
1134
2625
|
product_variant_id,
|
|
1135
2626
|
updates,
|
|
1136
2627
|
unique_identification_number,
|
|
1137
|
-
|
|
1138
|
-
|
|
2628
|
+
identity_key,
|
|
2629
|
+
product_sku,
|
|
2630
|
+
product_bundle,
|
|
2631
|
+
booking
|
|
1139
2632
|
} = params;
|
|
1140
2633
|
const tempOrder = this.ensureTempOrder();
|
|
1141
2634
|
const identityLookup = {
|
|
@@ -1144,12 +2637,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1144
2637
|
};
|
|
1145
2638
|
if (unique_identification_number !== void 0) {
|
|
1146
2639
|
identityLookup.unique_identification_number = unique_identification_number;
|
|
2640
|
+
if (identity_key === void 0) {
|
|
2641
|
+
identityLookup.identity_key = unique_identification_number;
|
|
2642
|
+
}
|
|
1147
2643
|
}
|
|
1148
|
-
if (
|
|
1149
|
-
identityLookup.
|
|
2644
|
+
if (identity_key !== void 0) {
|
|
2645
|
+
identityLookup.identity_key = identity_key;
|
|
2646
|
+
}
|
|
2647
|
+
if (product_sku !== void 0)
|
|
2648
|
+
identityLookup.product_sku = product_sku;
|
|
1150
2649
|
if (product_bundle !== void 0)
|
|
1151
2650
|
identityLookup.product_bundle = product_bundle;
|
|
1152
|
-
|
|
2651
|
+
let productIndex = -1;
|
|
2652
|
+
if (unique_identification_number !== void 0) {
|
|
2653
|
+
const targetUid = String(unique_identification_number);
|
|
2654
|
+
productIndex = tempOrder.products.findIndex((item) => {
|
|
2655
|
+
var _a2;
|
|
2656
|
+
return String(
|
|
2657
|
+
((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
|
|
2658
|
+
) === targetUid;
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
if (productIndex === -1) {
|
|
2662
|
+
productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
|
|
2663
|
+
}
|
|
1153
2664
|
if (productIndex === -1) {
|
|
1154
2665
|
throw new Error("[Order] 目标商品不存在,无法更新");
|
|
1155
2666
|
}
|
|
@@ -1163,12 +2674,49 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1163
2674
|
...targetProduct.metadata || {},
|
|
1164
2675
|
...(updates == null ? void 0 : updates.metadata) || {},
|
|
1165
2676
|
unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
|
|
2677
|
+
},
|
|
2678
|
+
product_sku: {
|
|
2679
|
+
...targetProduct.product_sku || { option: [] },
|
|
2680
|
+
...(updates == null ? void 0 : updates.product_sku) && typeof updates.product_sku === "object" ? updates.product_sku : {},
|
|
2681
|
+
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
2682
|
}
|
|
1167
2683
|
};
|
|
1168
2684
|
nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
|
|
1169
2685
|
const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
|
|
1170
|
-
const callerUpdatesMainMeta = ((
|
|
1171
|
-
|
|
2686
|
+
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;
|
|
2687
|
+
const isPersistedOrderLine = targetProduct.order_detail_id !== void 0 && targetProduct.order_detail_id !== null;
|
|
2688
|
+
const callerChangesDiscountList = Array.isArray(updates == null ? void 0 : updates.discount_list) && updates.discount_list.length > 0 && !isSameDiscountList(updates.discount_list, targetProduct.discount_list);
|
|
2689
|
+
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;
|
|
2690
|
+
const callerAllowsBookingReprice = (() => {
|
|
2691
|
+
if (params.allow_booking_reprice !== true || !booking || !callerUpdatesTopPrice || !callerUpdatesMainMeta) {
|
|
2692
|
+
return false;
|
|
2693
|
+
}
|
|
2694
|
+
const hasChangedPrice = (nextValue, currentValue) => {
|
|
2695
|
+
if (nextValue === void 0 || nextValue === null || nextValue === "") {
|
|
2696
|
+
return false;
|
|
2697
|
+
}
|
|
2698
|
+
return !new import_decimal.default(Number(nextValue) || 0).equals(
|
|
2699
|
+
new import_decimal.default(Number(currentValue) || 0)
|
|
2700
|
+
);
|
|
2701
|
+
};
|
|
2702
|
+
return hasChangedPrice(updates.selling_price, targetProduct.selling_price) || hasChangedPrice(updates.original_price, targetProduct.original_price);
|
|
2703
|
+
})();
|
|
2704
|
+
if (isPersistedOrderLine && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
|
|
2705
|
+
nextProduct.selling_price = targetProduct.selling_price;
|
|
2706
|
+
nextProduct.original_price = targetProduct.original_price;
|
|
2707
|
+
nextProduct.payment_price = targetProduct.payment_price;
|
|
2708
|
+
nextProduct.metadata = {
|
|
2709
|
+
...nextProduct.metadata || {},
|
|
2710
|
+
source_product_price: (_i = targetProduct.metadata) == null ? void 0 : _i.source_product_price,
|
|
2711
|
+
main_product_selling_price: (_j = targetProduct.metadata) == null ? void 0 : _j.main_product_selling_price,
|
|
2712
|
+
main_product_original_price: (_k = targetProduct.metadata) == null ? void 0 : _k.main_product_original_price,
|
|
2713
|
+
price_schema_version: ((_l = targetProduct.metadata) == null ? void 0 : _l.price_schema_version) ?? 2
|
|
2714
|
+
};
|
|
2715
|
+
nextProduct.product_bundle = this.preservePersistedBundlePriceFields(
|
|
2716
|
+
targetProduct.product_bundle,
|
|
2717
|
+
nextProduct.product_bundle
|
|
2718
|
+
);
|
|
2719
|
+
} else if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
|
|
1172
2720
|
const existedMeta = nextProduct.metadata || {};
|
|
1173
2721
|
nextProduct.metadata = { ...existedMeta };
|
|
1174
2722
|
delete nextProduct.metadata.source_product_price;
|
|
@@ -1176,39 +2724,313 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1176
2724
|
delete nextProduct.metadata.main_product_original_price;
|
|
1177
2725
|
delete nextProduct.metadata.price_schema_version;
|
|
1178
2726
|
}
|
|
1179
|
-
|
|
2727
|
+
let normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
|
|
2728
|
+
nextProduct,
|
|
2729
|
+
(0, import_utils3.normalizeOrderProduct)(nextProduct)
|
|
2730
|
+
);
|
|
2731
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2732
|
+
normalizedProduct.discount_list
|
|
2733
|
+
);
|
|
2734
|
+
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);
|
|
2735
|
+
if (!booking && preservedBookingUid) {
|
|
2736
|
+
normalizedProduct.booking_uid = preservedBookingUid;
|
|
2737
|
+
normalizedProduct.metadata = {
|
|
2738
|
+
...normalizedProduct.metadata || {},
|
|
2739
|
+
booking_uid: preservedBookingUid
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
if (booking) {
|
|
2743
|
+
const productUid = String(
|
|
2744
|
+
((_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)()
|
|
2745
|
+
);
|
|
2746
|
+
normalizedProduct.metadata = {
|
|
2747
|
+
...normalizedProduct.metadata || {},
|
|
2748
|
+
unique_identification_number: productUid
|
|
2749
|
+
};
|
|
2750
|
+
const linked = this.createLinkedProductAndBooking({
|
|
2751
|
+
product: {
|
|
2752
|
+
...normalizedProduct,
|
|
2753
|
+
unique_identification_number: productUid
|
|
2754
|
+
},
|
|
2755
|
+
booking
|
|
2756
|
+
});
|
|
2757
|
+
this.removeLinkedBookingsForProduct(tempOrder, targetProduct);
|
|
2758
|
+
normalizedProduct = {
|
|
2759
|
+
...normalizedProduct,
|
|
2760
|
+
booking_uid: linked.bookingUid,
|
|
2761
|
+
metadata: {
|
|
2762
|
+
...normalizedProduct.metadata || {},
|
|
2763
|
+
booking_uid: linked.bookingUid,
|
|
2764
|
+
unique_identification_number: productUid
|
|
2765
|
+
}
|
|
2766
|
+
};
|
|
2767
|
+
tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
|
|
2768
|
+
}
|
|
2769
|
+
tempOrder.products[productIndex] = normalizedProduct;
|
|
2770
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
1180
2771
|
this.captureProductRuntime(
|
|
1181
2772
|
tempOrder,
|
|
1182
2773
|
updates,
|
|
1183
2774
|
tempOrder.products[productIndex],
|
|
1184
|
-
(
|
|
2775
|
+
(_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
|
|
1185
2776
|
);
|
|
2777
|
+
await this.applyPromotion();
|
|
1186
2778
|
this.applyDiscount();
|
|
2779
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1187
2780
|
await this.recalculateSummary({ createIfMissing: true });
|
|
1188
2781
|
this.persistTempOrder();
|
|
1189
2782
|
return tempOrder.products;
|
|
1190
2783
|
}
|
|
1191
|
-
async
|
|
2784
|
+
async updateOrderProductQuantity(params) {
|
|
2785
|
+
var _a;
|
|
2786
|
+
const {
|
|
2787
|
+
product_id,
|
|
2788
|
+
product_variant_id,
|
|
2789
|
+
num,
|
|
2790
|
+
unique_identification_number,
|
|
2791
|
+
identity_key,
|
|
2792
|
+
product_sku,
|
|
2793
|
+
product_bundle
|
|
2794
|
+
} = params;
|
|
2795
|
+
const tempOrder = this.ensureTempOrder();
|
|
2796
|
+
const identityLookup = {
|
|
2797
|
+
product_id,
|
|
2798
|
+
product_variant_id
|
|
2799
|
+
};
|
|
2800
|
+
if (unique_identification_number !== void 0) {
|
|
2801
|
+
identityLookup.unique_identification_number = unique_identification_number;
|
|
2802
|
+
if (identity_key === void 0) {
|
|
2803
|
+
identityLookup.identity_key = unique_identification_number;
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
if (identity_key !== void 0)
|
|
2807
|
+
identityLookup.identity_key = identity_key;
|
|
2808
|
+
if (product_sku !== void 0)
|
|
2809
|
+
identityLookup.product_sku = product_sku;
|
|
2810
|
+
if (product_bundle !== void 0)
|
|
2811
|
+
identityLookup.product_bundle = product_bundle;
|
|
2812
|
+
let productIndex = -1;
|
|
2813
|
+
if (unique_identification_number !== void 0) {
|
|
2814
|
+
const targetUid = String(unique_identification_number);
|
|
2815
|
+
productIndex = tempOrder.products.findIndex((item) => {
|
|
2816
|
+
var _a2;
|
|
2817
|
+
return String(
|
|
2818
|
+
((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
|
|
2819
|
+
) === targetUid;
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
if (productIndex === -1) {
|
|
2823
|
+
productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
|
|
2824
|
+
}
|
|
2825
|
+
if (productIndex === -1) {
|
|
2826
|
+
throw new Error("[Order] 目标商品不存在,无法更新数量");
|
|
2827
|
+
}
|
|
2828
|
+
const targetProduct = tempOrder.products[productIndex];
|
|
2829
|
+
const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
|
|
2830
|
+
...targetProduct,
|
|
2831
|
+
num: (0, import_utils3.getSafeProductNum)(num),
|
|
2832
|
+
metadata: {
|
|
2833
|
+
...targetProduct.metadata || {},
|
|
2834
|
+
unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
|
|
2835
|
+
}
|
|
2836
|
+
});
|
|
2837
|
+
normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
2838
|
+
normalizedProduct.discount_list
|
|
2839
|
+
);
|
|
2840
|
+
tempOrder.products[productIndex] = normalizedProduct;
|
|
2841
|
+
await this.applyPromotion();
|
|
2842
|
+
this.applyDiscount();
|
|
2843
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2844
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2845
|
+
this.persistTempOrder();
|
|
2846
|
+
return tempOrder.products;
|
|
2847
|
+
}
|
|
2848
|
+
updateOrderBooking(params) {
|
|
2849
|
+
const { unique_identification_number, updates } = params;
|
|
1192
2850
|
const tempOrder = this.ensureTempOrder();
|
|
1193
|
-
|
|
1194
|
-
|
|
2851
|
+
const bookingUid = String(unique_identification_number || "");
|
|
2852
|
+
const bookingIndex = this.findBookingIndexByUniqueIdentificationNumber(
|
|
2853
|
+
tempOrder,
|
|
2854
|
+
bookingUid
|
|
1195
2855
|
);
|
|
2856
|
+
if (!bookingUid || bookingIndex === -1) {
|
|
2857
|
+
throw new Error("[Order] 目标 booking 不存在,无法更新");
|
|
2858
|
+
}
|
|
2859
|
+
const targetBooking = tempOrder.bookings[bookingIndex] || {};
|
|
2860
|
+
const nextBooking = {
|
|
2861
|
+
...targetBooking,
|
|
2862
|
+
...updates,
|
|
2863
|
+
metadata: {
|
|
2864
|
+
...targetBooking.metadata || {},
|
|
2865
|
+
...updates.metadata || {},
|
|
2866
|
+
unique_identification_number: bookingUid
|
|
2867
|
+
}
|
|
2868
|
+
};
|
|
2869
|
+
this.syncBookingMetadataHolder(nextBooking, nextBooking.metadata);
|
|
2870
|
+
nextBooking.is_all = (0, import_utils.normalizeBookingIsAll)(nextBooking);
|
|
2871
|
+
nextBooking.sub_type = (0, import_utils.normalizeBookingSubType)(nextBooking);
|
|
2872
|
+
tempOrder.bookings[bookingIndex] = nextBooking;
|
|
2873
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2874
|
+
this.persistTempOrder();
|
|
2875
|
+
return tempOrder.bookings;
|
|
2876
|
+
}
|
|
2877
|
+
/**
|
|
2878
|
+
* 商品行写路径收尾:促销 → 折扣 → 清洗 → summary → 持久化。
|
|
2879
|
+
* 批量删除等多行变更场景只应调用一次,避免 N 次 applyPromotion。
|
|
2880
|
+
*
|
|
2881
|
+
* @example
|
|
2882
|
+
* await this.finalizeAfterProductsMutation(tempOrder);
|
|
2883
|
+
*/
|
|
2884
|
+
async finalizeAfterProductsMutation(tempOrder) {
|
|
2885
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2886
|
+
await this.applyPromotion();
|
|
1196
2887
|
this.applyDiscount();
|
|
2888
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
1197
2889
|
await this.recalculateSummary({ createIfMissing: true });
|
|
1198
2890
|
this.persistTempOrder();
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* 批量按 identity 删除购物车行,末尾仅一次促销重算。
|
|
2894
|
+
*
|
|
2895
|
+
* @example
|
|
2896
|
+
* await order.removeProductsFromOrder([identityA, identityB]);
|
|
2897
|
+
*/
|
|
2898
|
+
async removeProductsFromOrder(identities) {
|
|
2899
|
+
var _a, _b, _c, _d;
|
|
2900
|
+
const tempOrder = this.ensureTempOrder();
|
|
2901
|
+
if (!identities.length) {
|
|
2902
|
+
return tempOrder.products;
|
|
2903
|
+
}
|
|
2904
|
+
const productsBeforeRemove = tempOrder.products || [];
|
|
2905
|
+
const bookingsBeforeRemove = tempOrder.bookings || [];
|
|
2906
|
+
const matchedProducts = productsBeforeRemove.filter((item) => {
|
|
2907
|
+
return identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
|
|
2908
|
+
});
|
|
2909
|
+
const removedProducts = [];
|
|
2910
|
+
tempOrder.products = tempOrder.products.filter((item) => {
|
|
2911
|
+
const shouldRemove = identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
|
|
2912
|
+
if (shouldRemove)
|
|
2913
|
+
removedProducts.push(item);
|
|
2914
|
+
return !shouldRemove;
|
|
2915
|
+
});
|
|
2916
|
+
for (const product of removedProducts) {
|
|
2917
|
+
this.removeLinkedBookingsForProduct(tempOrder, product);
|
|
2918
|
+
}
|
|
2919
|
+
const linkedBookingUidsToRemove = /* @__PURE__ */ new Set();
|
|
2920
|
+
for (const product of matchedProducts) {
|
|
2921
|
+
const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
|
|
2922
|
+
const productBookingUid = (product == null ? void 0 : product.booking_uid) || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.booking_uid);
|
|
2923
|
+
const isAddTimeProduct = ((_c = product == null ? void 0 : product.metadata) == null ? void 0 : _c.product_add_schedule_time) !== void 0 && ((_d = product == null ? void 0 : product.metadata) == null ? void 0 : _d.product_add_schedule_time) !== null;
|
|
2924
|
+
if (isAddTimeProduct)
|
|
2925
|
+
continue;
|
|
2926
|
+
if (productBookingUid !== void 0 && productBookingUid !== null && productBookingUid !== "") {
|
|
2927
|
+
linkedBookingUidsToRemove.add(String(productBookingUid));
|
|
2928
|
+
}
|
|
2929
|
+
if (productUid !== void 0 && productUid !== null && productUid !== "") {
|
|
2930
|
+
bookingsBeforeRemove.forEach((booking) => {
|
|
2931
|
+
const bookingUid = this.getBookingUniqueIdentificationNumber(booking);
|
|
2932
|
+
if (bookingUid && String((booking == null ? void 0 : booking.product_uid) || "") === String(productUid)) {
|
|
2933
|
+
linkedBookingUidsToRemove.add(bookingUid);
|
|
2934
|
+
}
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
if (linkedBookingUidsToRemove.size > 0) {
|
|
2939
|
+
tempOrder.products = (tempOrder.products || []).filter((line) => {
|
|
2940
|
+
var _a2, _b2, _c2;
|
|
2941
|
+
const lineBookingUid = ((_a2 = line == null ? void 0 : line.metadata) == null ? void 0 : _a2.booking_uid) || (line == null ? void 0 : line.booking_uid);
|
|
2942
|
+
const isAddTimeProduct = ((_b2 = line == null ? void 0 : line.metadata) == null ? void 0 : _b2.product_add_schedule_time) !== void 0 && ((_c2 = line == null ? void 0 : line.metadata) == null ? void 0 : _c2.product_add_schedule_time) !== null;
|
|
2943
|
+
return !(isAddTimeProduct && lineBookingUid !== void 0 && lineBookingUid !== null && linkedBookingUidsToRemove.has(String(lineBookingUid)));
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
await this.finalizeAfterProductsMutation(tempOrder);
|
|
1199
2947
|
return tempOrder.products;
|
|
1200
2948
|
}
|
|
2949
|
+
async removeProductFromOrder(identity) {
|
|
2950
|
+
return this.removeProductsFromOrder([identity]);
|
|
2951
|
+
}
|
|
2952
|
+
/**
|
|
2953
|
+
* 仅清空购物车行(products / bookings),不重置整单。
|
|
2954
|
+
* 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
|
|
2955
|
+
*/
|
|
2956
|
+
async clearOrderCartLines() {
|
|
2957
|
+
const tempOrder = this.ensureTempOrder();
|
|
2958
|
+
tempOrder.products = [];
|
|
2959
|
+
tempOrder.bookings = [];
|
|
2960
|
+
this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2961
|
+
if (tempOrder._extend && typeof tempOrder._extend === "object") {
|
|
2962
|
+
tempOrder._extend = {
|
|
2963
|
+
...tempOrder._extend,
|
|
2964
|
+
productsByUid: {}
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
2967
|
+
await this.applyPromotion();
|
|
2968
|
+
this.applyDiscount();
|
|
2969
|
+
this.sanitizeTempOrderProducts(tempOrder);
|
|
2970
|
+
await this.recalculateSummary({ createIfMissing: true });
|
|
2971
|
+
this.persistTempOrder();
|
|
2972
|
+
return tempOrder;
|
|
2973
|
+
}
|
|
1201
2974
|
// ─── TempOrder: 提交 ───
|
|
2975
|
+
buildCurrentSubmitPayloadForLocalPrint(params) {
|
|
2976
|
+
var _a, _b, _c;
|
|
2977
|
+
const tempOrder = this.ensureTempOrder();
|
|
2978
|
+
this.persistTempOrder();
|
|
2979
|
+
const payload = (0, import_utils.buildSubmitPayload)({
|
|
2980
|
+
tempOrder,
|
|
2981
|
+
cacheId: (params == null ? void 0 : params.cacheId) ?? this.cacheId,
|
|
2982
|
+
platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
|
|
2983
|
+
businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
|
|
2984
|
+
channel: params == null ? void 0 : params.channel,
|
|
2985
|
+
type: params == null ? void 0 : params.type,
|
|
2986
|
+
summary: this.store.summary || (0, import_utils.createEmptySummary)(),
|
|
2987
|
+
enhance: (nextPayload) => ({
|
|
2988
|
+
...nextPayload,
|
|
2989
|
+
order_number: tempOrder.order_number ?? nextPayload.order_number ?? null,
|
|
2990
|
+
shop_order_number: tempOrder.shop_order_number ?? nextPayload.shop_order_number ?? null,
|
|
2991
|
+
shop_full_order_number: tempOrder.shop_full_order_number ?? nextPayload.shop_full_order_number ?? null,
|
|
2992
|
+
small_ticket_data_flag: 1
|
|
2993
|
+
})
|
|
2994
|
+
});
|
|
2995
|
+
payload.created_at = void 0;
|
|
2996
|
+
return payload;
|
|
2997
|
+
}
|
|
2998
|
+
async applyLocalPrintOrderNumbers(order) {
|
|
2999
|
+
const tempOrder = this.ensureTempOrder();
|
|
3000
|
+
if (!order || typeof order !== "object")
|
|
3001
|
+
return tempOrder;
|
|
3002
|
+
const shopOrderNumber = order.shop_order_number;
|
|
3003
|
+
const shopFullOrderNumber = order.shop_full_order_number;
|
|
3004
|
+
if (shopOrderNumber !== void 0 && shopOrderNumber !== null && shopOrderNumber !== "") {
|
|
3005
|
+
tempOrder.shop_order_number = String(shopOrderNumber);
|
|
3006
|
+
}
|
|
3007
|
+
if (shopFullOrderNumber !== void 0 && shopFullOrderNumber !== null && shopFullOrderNumber !== "") {
|
|
3008
|
+
tempOrder.shop_full_order_number = String(shopFullOrderNumber);
|
|
3009
|
+
}
|
|
3010
|
+
this.persistTempOrder();
|
|
3011
|
+
await this.saveDraft();
|
|
3012
|
+
return tempOrder;
|
|
3013
|
+
}
|
|
1202
3014
|
/**
|
|
1203
3015
|
* 提交当前 Sales tempOrder。
|
|
1204
3016
|
*
|
|
1205
3017
|
* smallTicketDataFlag 用于 B 端 checkout 小票数据返回。PaymentModal 在支付提交时
|
|
1206
|
-
* 应传 1,确保 /order/sales/checkout 返回打印所需数据。
|
|
3018
|
+
* 应传 1,确保 /shop/order/sales/checkout 返回打印所需数据。
|
|
1207
3019
|
*/
|
|
1208
3020
|
async submitTempOrder(params) {
|
|
1209
|
-
|
|
3021
|
+
return this.runSubmitTempOrder(params);
|
|
3022
|
+
}
|
|
3023
|
+
async submitTempOrderAsync(params) {
|
|
3024
|
+
return this.runSubmitTempOrder({
|
|
3025
|
+
...params,
|
|
3026
|
+
syncMode: true
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
async runSubmitTempOrder(params) {
|
|
3030
|
+
var _a, _b, _c, _d, _e;
|
|
1210
3031
|
const tempOrder = this.ensureTempOrder();
|
|
1211
3032
|
this.persistTempOrder();
|
|
3033
|
+
const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
|
|
1212
3034
|
const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
|
|
1213
3035
|
const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
|
|
1214
3036
|
const hasPaymentStatusOverride = (params == null ? void 0 : params.paymentStatus) !== void 0;
|
|
@@ -1224,26 +3046,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1224
3046
|
...hasPaymentStatusOverride ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
|
|
1225
3047
|
...hasSmallTicketDataFlagOverride ? { small_ticket_data_flag: params == null ? void 0 : params.smallTicketDataFlag } : {}
|
|
1226
3048
|
};
|
|
1227
|
-
|
|
3049
|
+
const enhancedPayload = (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
|
|
3050
|
+
return enhancedPayload;
|
|
1228
3051
|
} : void 0;
|
|
1229
3052
|
const payload = (0, import_utils.buildSubmitPayload)({
|
|
1230
3053
|
tempOrder,
|
|
1231
3054
|
cacheId: effectiveCacheId,
|
|
1232
3055
|
platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
|
|
1233
|
-
businessCode: params == null ? void 0 : params.businessCode,
|
|
3056
|
+
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
3057
|
channel: params == null ? void 0 : params.channel,
|
|
1235
3058
|
type: params == null ? void 0 : params.type,
|
|
3059
|
+
summary: latestSummary,
|
|
3060
|
+
request_unique_idempotency_token: params == null ? void 0 : params.request_unique_idempotency_token,
|
|
1236
3061
|
enhance: enhancePayload
|
|
1237
3062
|
});
|
|
3063
|
+
if (params == null ? void 0 : params.syncMode) {
|
|
3064
|
+
payload.sync_mode = true;
|
|
3065
|
+
}
|
|
3066
|
+
if (!payload.created_at) {
|
|
3067
|
+
payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
3068
|
+
}
|
|
1238
3069
|
await this.saveDraft();
|
|
1239
3070
|
let result;
|
|
1240
3071
|
try {
|
|
1241
3072
|
this.logInfo("submitTempOrder calling sales checkout", {
|
|
1242
3073
|
orderId: payload.order_id,
|
|
1243
3074
|
externalSaleNumber: payload.external_sale_number,
|
|
3075
|
+
requestUniqueIdempotencyToken: payload.request_unique_idempotency_token,
|
|
1244
3076
|
paymentStatus: payload.payment_status,
|
|
1245
|
-
paymentsCount: ((
|
|
1246
|
-
smallTicketDataFlag: payload.small_ticket_data_flag
|
|
3077
|
+
paymentsCount: ((_d = payload.payments) == null ? void 0 : _d.length) || 0,
|
|
3078
|
+
smallTicketDataFlag: payload.small_ticket_data_flag,
|
|
3079
|
+
syncMode: payload.sync_mode
|
|
1247
3080
|
});
|
|
1248
3081
|
result = await this.submitSalesOrder({
|
|
1249
3082
|
query: payload
|
|
@@ -1261,7 +3094,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1261
3094
|
orderId: payload.order_id,
|
|
1262
3095
|
externalSaleNumber: payload.external_sale_number,
|
|
1263
3096
|
paymentStatus: payload.payment_status,
|
|
1264
|
-
paymentsCount: ((
|
|
3097
|
+
paymentsCount: ((_e = payload.payments) == null ? void 0 : _e.length) || 0
|
|
1265
3098
|
});
|
|
1266
3099
|
throw error;
|
|
1267
3100
|
}
|
|
@@ -1271,6 +3104,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1271
3104
|
return result;
|
|
1272
3105
|
}
|
|
1273
3106
|
const submittedOrderId = this.extractOrderIdFromSubmitResult(result);
|
|
3107
|
+
this.logInfo("runSubmitTempOrder: 提交成功", {
|
|
3108
|
+
submittedOrderId,
|
|
3109
|
+
result,
|
|
3110
|
+
tempOrder
|
|
3111
|
+
});
|
|
1274
3112
|
if (submittedOrderId !== null && submittedOrderId !== void 0) {
|
|
1275
3113
|
tempOrder.order_id = submittedOrderId;
|
|
1276
3114
|
const resultRecord = result;
|
|
@@ -1278,23 +3116,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1278
3116
|
submittedOrderId,
|
|
1279
3117
|
(resultRecord == null ? void 0 : resultRecord.data) || resultRecord || {}
|
|
1280
3118
|
);
|
|
3119
|
+
} else if (this.isLocalPendingSubmitResult(result)) {
|
|
3120
|
+
this.store.syncState = "local";
|
|
3121
|
+
} else {
|
|
3122
|
+
this.store.syncState = "submitted";
|
|
1281
3123
|
}
|
|
1282
3124
|
return result;
|
|
1283
3125
|
}
|
|
1284
3126
|
async markLocalOrderSynced(orderId, remoteOrder) {
|
|
1285
3127
|
const tempOrder = this.ensureTempOrder();
|
|
1286
3128
|
tempOrder.order_id = orderId;
|
|
3129
|
+
this.applyRemoteOrderNumbersToTempOrder(tempOrder, remoteOrder);
|
|
1287
3130
|
this.store.lastOrderInfo = remoteOrder;
|
|
1288
3131
|
this.store.syncState = "submitted";
|
|
1289
3132
|
this.persistTempOrder();
|
|
1290
3133
|
await this.saveDraft();
|
|
1291
3134
|
}
|
|
3135
|
+
applyRemoteOrderNumbersToTempOrder(tempOrder, remoteOrder) {
|
|
3136
|
+
const applyOrderNumber = (key) => {
|
|
3137
|
+
const value = remoteOrder == null ? void 0 : remoteOrder[key];
|
|
3138
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
3139
|
+
tempOrder[key] = String(value);
|
|
3140
|
+
}
|
|
3141
|
+
};
|
|
3142
|
+
applyOrderNumber("order_number");
|
|
3143
|
+
applyOrderNumber("shop_order_number");
|
|
3144
|
+
applyOrderNumber("shop_full_order_number");
|
|
3145
|
+
}
|
|
1292
3146
|
isSubmitResponseRejected(response) {
|
|
1293
3147
|
const isErrorCode = (response == null ? void 0 : response.code) !== void 0 && response.code !== 200 && response.code !== "200";
|
|
1294
3148
|
const isErrorStatus = (response == null ? void 0 : response.status) === false || typeof (response == null ? void 0 : response.status) === "number" && response.status >= 400;
|
|
1295
3149
|
const isErrorSuccess = (response == null ? void 0 : response.success) === false;
|
|
1296
3150
|
return isErrorCode || isErrorStatus || isErrorSuccess;
|
|
1297
3151
|
}
|
|
3152
|
+
isLocalPendingSubmitResult(response) {
|
|
3153
|
+
const data = (response == null ? void 0 : response.data) && typeof response.data === "object" ? response.data : response;
|
|
3154
|
+
return Number(data == null ? void 0 : data.need_sync) === 1;
|
|
3155
|
+
}
|
|
1298
3156
|
isSubmitErrorResponse(response) {
|
|
1299
3157
|
if (!response || typeof response !== "object")
|
|
1300
3158
|
return false;
|
|
@@ -1322,26 +3180,51 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1322
3180
|
}
|
|
1323
3181
|
});
|
|
1324
3182
|
}
|
|
3183
|
+
generateIdempotencyToken() {
|
|
3184
|
+
const tempOrder = this.ensureTempOrder();
|
|
3185
|
+
const token = this.buildPaymentSyncIdempotencyToken(
|
|
3186
|
+
tempOrder,
|
|
3187
|
+
tempOrder.payments
|
|
3188
|
+
);
|
|
3189
|
+
return `${token}_${Date.now()}`;
|
|
3190
|
+
}
|
|
1325
3191
|
async syncPaymentsToOrder(params) {
|
|
1326
3192
|
const tempOrder = this.ensureTempOrder();
|
|
1327
3193
|
const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
|
|
1328
3194
|
params.payments || []
|
|
1329
3195
|
);
|
|
3196
|
+
const paymentTotal = this.calculatePaymentTotal(mappedPayments);
|
|
3197
|
+
const targetAmount = this.getPaymentTargetAmount();
|
|
3198
|
+
const isFullyPaid = targetAmount.lte(0) ? true : paymentTotal.gte(targetAmount);
|
|
3199
|
+
const paymentStatus = isFullyPaid ? params.paymentStatus || "paid" : "partially_paid";
|
|
1330
3200
|
tempOrder.payments = mappedPayments;
|
|
1331
|
-
|
|
1332
|
-
tempOrder.payment_status = params.paymentStatus;
|
|
3201
|
+
tempOrder.payment_status = paymentStatus;
|
|
1333
3202
|
this.persistTempOrder();
|
|
1334
3203
|
await this.saveDraft();
|
|
1335
|
-
|
|
1336
|
-
const targetAmount = this.getPaymentTargetAmount();
|
|
1337
|
-
const isFullyPaid = targetAmount.lte(0) ? false : paymentTotal.gte(targetAmount);
|
|
1338
|
-
if (!isFullyPaid || !params.submitWhenPaid) {
|
|
3204
|
+
if (!params.submitWhenPaid) {
|
|
1339
3205
|
return { isFullyPaid };
|
|
1340
3206
|
}
|
|
3207
|
+
if (this.store.syncState === "submitting") {
|
|
3208
|
+
return { isFullyPaid };
|
|
3209
|
+
}
|
|
3210
|
+
this.store.syncState = "submitting";
|
|
3211
|
+
const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(
|
|
3212
|
+
tempOrder,
|
|
3213
|
+
mappedPayments
|
|
3214
|
+
);
|
|
1341
3215
|
const submitResult = await this.submitTempOrder({
|
|
1342
3216
|
payments: mappedPayments,
|
|
1343
|
-
paymentStatus
|
|
1344
|
-
smallTicketDataFlag: params.smallTicketDataFlag
|
|
3217
|
+
paymentStatus,
|
|
3218
|
+
smallTicketDataFlag: params.smallTicketDataFlag,
|
|
3219
|
+
businessCode: params.businessCode,
|
|
3220
|
+
channel: params.channel,
|
|
3221
|
+
enhancePayload: (payload) => {
|
|
3222
|
+
const nextPayload = {
|
|
3223
|
+
...payload,
|
|
3224
|
+
request_unique_idempotency_token: paymentSyncIdempotencyToken
|
|
3225
|
+
};
|
|
3226
|
+
return nextPayload;
|
|
3227
|
+
}
|
|
1345
3228
|
});
|
|
1346
3229
|
return { isFullyPaid, submitResult };
|
|
1347
3230
|
}
|
|
@@ -1477,7 +3360,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1477
3360
|
* Checkout 专用:创建订单到后端
|
|
1478
3361
|
*
|
|
1479
3362
|
* 专门为 Checkout 模块设计的订单创建方法,
|
|
1480
|
-
*
|
|
3363
|
+
* 通过 OS Server 调用 checkout 接口创建订单
|
|
1481
3364
|
* 接收已经处理好的订单数据,无需再处理购物车
|
|
1482
3365
|
*
|
|
1483
3366
|
* @param params Checkout 订单参数(已处理的订单数据)
|
|
@@ -1546,7 +3429,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1546
3429
|
orderData.schedule_date = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1547
3430
|
}
|
|
1548
3431
|
console.log("[Order] 调用后端接口创建订单:", {
|
|
1549
|
-
url: "/order/checkout",
|
|
3432
|
+
url: "/shop/order/checkout",
|
|
1550
3433
|
orderType: orderData.type,
|
|
1551
3434
|
platform: orderData.platform,
|
|
1552
3435
|
isDeposit: orderData.is_deposit,
|
|
@@ -1557,7 +3440,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1557
3440
|
paymentsMethods: ((_m = orderData.payments) == null ? void 0 : _m.map((p) => p.code)) || []
|
|
1558
3441
|
});
|
|
1559
3442
|
this.logInfo("Calling backend checkout API", {
|
|
1560
|
-
url: "/order/checkout",
|
|
3443
|
+
url: "/shop/order/checkout",
|
|
1561
3444
|
orderType: orderData.type,
|
|
1562
3445
|
platform: orderData.platform,
|
|
1563
3446
|
isDeposit: orderData.is_deposit,
|
|
@@ -1579,7 +3462,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1579
3462
|
hasOrderId: !!orderData.order_id,
|
|
1580
3463
|
smallTicketDataFlag: orderData.small_ticket_data_flag
|
|
1581
3464
|
});
|
|
1582
|
-
const response = await this.request.post("/order/checkout", orderData
|
|
3465
|
+
const response = await this.request.post("/order/checkout", orderData, {
|
|
3466
|
+
osServer: true,
|
|
3467
|
+
customToast: () => {
|
|
3468
|
+
}
|
|
3469
|
+
});
|
|
1583
3470
|
this.logInfo("Order API called successfully", {
|
|
1584
3471
|
response
|
|
1585
3472
|
});
|
|
@@ -1599,7 +3486,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1599
3486
|
async submitSalesOrder(params) {
|
|
1600
3487
|
const { url, query } = params;
|
|
1601
3488
|
const fetchUrl = url || "/order/sales/checkout";
|
|
1602
|
-
return this.request.post(fetchUrl, query, { customToast: () => {
|
|
3489
|
+
return this.request.post(fetchUrl, query, { osServer: true, customToast: () => {
|
|
1603
3490
|
} });
|
|
1604
3491
|
}
|
|
1605
3492
|
/**
|
|
@@ -1623,13 +3510,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1623
3510
|
emails: params.emails
|
|
1624
3511
|
});
|
|
1625
3512
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
|
|
3513
|
+
async getSalesOrderByLookup(params) {
|
|
3514
|
+
const lookup = params.lookup === void 0 || params.lookup === null ? "" : String(params.lookup).trim();
|
|
3515
|
+
if (!lookup) {
|
|
3516
|
+
throw new Error("加载销售详情需要 lookup");
|
|
3517
|
+
}
|
|
3518
|
+
if (lookup.startsWith("LOCAL_")) {
|
|
3519
|
+
params.forceRemote = false;
|
|
3520
|
+
}
|
|
3521
|
+
const res = await this.request.get(`/order/sales/${encodeURIComponent(lookup)}`, {
|
|
3522
|
+
with: ["products", "bookings", "payments", "customer", "summary", "contacts_info"],
|
|
3523
|
+
...params.forceRemote ? { forceRemote: true } : {}
|
|
3524
|
+
}, { osServer: true });
|
|
1633
3525
|
if (res.code === 200) {
|
|
1634
3526
|
this.store.lastOrderInfo = res.data;
|
|
1635
3527
|
}
|
|
@@ -1642,58 +3534,64 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1642
3534
|
* 例如数组字段、商品行唯一值、价格 metadata、summary 派生状态和 _extend。
|
|
1643
3535
|
*/
|
|
1644
3536
|
async hydrateTempOrderFromRecord(record, options) {
|
|
3537
|
+
var _a, _b, _c;
|
|
1645
3538
|
const raw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
|
|
3539
|
+
const nextTempOrder = this.normalizeTempOrderForRuntime(raw);
|
|
3540
|
+
const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
|
|
3541
|
+
const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
|
|
3542
|
+
this.store.tempOrder = nextTempOrder;
|
|
3543
|
+
this.store.summary = {
|
|
3544
|
+
...(0, import_utils.createEmptySummary)(),
|
|
3545
|
+
...rawSummary,
|
|
3546
|
+
surcharges: summarySurcharges
|
|
1649
3547
|
};
|
|
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];
|
|
3548
|
+
nextTempOrder._extend = {
|
|
3549
|
+
...nextTempOrder._extend || {},
|
|
3550
|
+
originalSalesSnapshot: {
|
|
3551
|
+
summary: (0, import_lodash_es.cloneDeep)(this.store.summary),
|
|
3552
|
+
products: (0, import_lodash_es.cloneDeep)(nextTempOrder.products || []),
|
|
3553
|
+
payments: (0, import_lodash_es.cloneDeep)(nextTempOrder.payments || []),
|
|
3554
|
+
surcharges: (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []),
|
|
3555
|
+
productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
|
|
1692
3556
|
}
|
|
1693
|
-
}
|
|
3557
|
+
};
|
|
3558
|
+
this.store.lastOrderInfo = raw.lastOrderInfo || raw;
|
|
3559
|
+
const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
|
|
3560
|
+
const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
|
|
3561
|
+
const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
|
|
3562
|
+
if (!shouldSkipEmptyDiscountSync) {
|
|
3563
|
+
await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
|
|
3564
|
+
await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
|
|
3565
|
+
}
|
|
3566
|
+
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
3567
|
+
await this.recalculateSummary({ createIfMissing: false });
|
|
3568
|
+
}
|
|
3569
|
+
this.persistTempOrder();
|
|
3570
|
+
return nextTempOrder;
|
|
3571
|
+
}
|
|
3572
|
+
normalizeTempOrderForRuntime(raw, options) {
|
|
3573
|
+
var _a, _b;
|
|
3574
|
+
const nextTempOrder = {
|
|
3575
|
+
...this.createDefaultTempOrderInstance(),
|
|
3576
|
+
...raw || {}
|
|
3577
|
+
};
|
|
3578
|
+
delete nextTempOrder.summary;
|
|
3579
|
+
delete nextTempOrder.lastOrderInfo;
|
|
3580
|
+
delete nextTempOrder.discount_list;
|
|
3581
|
+
delete nextTempOrder.shop_id;
|
|
3582
|
+
delete nextTempOrder.create_date;
|
|
3583
|
+
delete nextTempOrder.total_amount;
|
|
3584
|
+
delete nextTempOrder.expect_amount;
|
|
3585
|
+
delete nextTempOrder.paid_amount;
|
|
3586
|
+
delete nextTempOrder.shop_note;
|
|
3587
|
+
delete nextTempOrder.start_time;
|
|
3588
|
+
delete nextTempOrder.tax_fee;
|
|
3589
|
+
delete nextTempOrder.total_refund_amount;
|
|
3590
|
+
delete nextTempOrder.holder_id;
|
|
1694
3591
|
nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
|
|
1695
3592
|
nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
|
|
1696
|
-
|
|
3593
|
+
const rawProducts = Array.isArray(raw.products) ? raw.products : [];
|
|
3594
|
+
nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
|
|
1697
3595
|
nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => ({
|
|
1698
3596
|
...b || {},
|
|
1699
3597
|
is_all: (0, import_utils.normalizeBookingIsAll)(b || {}),
|
|
@@ -1701,7 +3599,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1701
3599
|
})) : [];
|
|
1702
3600
|
nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map((p) => ({ ...p || {} })) : [];
|
|
1703
3601
|
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
3602
|
nextTempOrder.relation_forms = Array.isArray(raw.relation_forms) ? raw.relation_forms.map((f) => ({ ...f || {} })) : [];
|
|
1706
3603
|
nextTempOrder.contacts = Array.isArray(raw.contacts) ? raw.contacts.map((c) => ({ ...c || {} })) : [];
|
|
1707
3604
|
nextTempOrder.contacts_info = raw.contacts_info && typeof raw.contacts_info === "object" && !Array.isArray(raw.contacts_info) ? { ...raw.contacts_info } : null;
|
|
@@ -1709,35 +3606,120 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1709
3606
|
...raw._extend,
|
|
1710
3607
|
productsByUid: raw._extend.productsByUid || {}
|
|
1711
3608
|
} : { productsByUid: {} };
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
3609
|
+
const tempOrderExtend = nextTempOrder._extend;
|
|
3610
|
+
const productsByUid = tempOrderExtend.productsByUid || {};
|
|
3611
|
+
for (const [index, product] of nextTempOrder.products.entries()) {
|
|
3612
|
+
const uid = (_a = product.metadata) == null ? void 0 : _a.unique_identification_number;
|
|
3613
|
+
if (!uid)
|
|
3614
|
+
continue;
|
|
3615
|
+
const existed = productsByUid[uid] && typeof productsByUid[uid] === "object" ? productsByUid[uid] : {};
|
|
3616
|
+
const rawProduct = rawProducts[index] && typeof rawProducts[index] === "object" ? rawProducts[index] : product;
|
|
3617
|
+
const origin = existed.origin ?? rawProduct._origin ?? ((_b = rawProduct.metadata) == null ? void 0 : _b.origin) ?? rawProduct;
|
|
3618
|
+
const originSnapshot = (0, import_lodash_es.cloneDeep)(origin);
|
|
3619
|
+
const productOptionString = this.buildHydratedProductOptionString(rawProduct) || this.buildHydratedProductOptionString(product);
|
|
3620
|
+
if (productOptionString && originSnapshot && typeof originSnapshot === "object") {
|
|
3621
|
+
if (originSnapshot.product_option_string === void 0) {
|
|
3622
|
+
originSnapshot.product_option_string = productOptionString;
|
|
3623
|
+
}
|
|
3624
|
+
if (originSnapshot.product_options_stirng === void 0) {
|
|
3625
|
+
originSnapshot.product_options_stirng = productOptionString;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
productsByUid[uid] = {
|
|
3629
|
+
...existed,
|
|
3630
|
+
origin: originSnapshot
|
|
3631
|
+
};
|
|
1718
3632
|
}
|
|
1719
|
-
|
|
3633
|
+
tempOrderExtend.productsByUid = productsByUid;
|
|
3634
|
+
if ((options == null ? void 0 : options.ensureIdentity) !== false) {
|
|
3635
|
+
this.ensureExternalSaleNumber(nextTempOrder);
|
|
3636
|
+
}
|
|
3637
|
+
nextTempOrder.vouchers = raw.vouchers || [];
|
|
1720
3638
|
return nextTempOrder;
|
|
1721
3639
|
}
|
|
3640
|
+
pickHydratedDisplayText(value) {
|
|
3641
|
+
if (value === void 0 || value === null)
|
|
3642
|
+
return "";
|
|
3643
|
+
if (typeof value === "string")
|
|
3644
|
+
return value;
|
|
3645
|
+
if (typeof value !== "object")
|
|
3646
|
+
return String(value);
|
|
3647
|
+
return value.auto || value.original || value.en || value["zh-CN"] || value["zh-HK"] || "";
|
|
3648
|
+
}
|
|
3649
|
+
formatHydratedNamePair(group, item) {
|
|
3650
|
+
const groupText = this.pickHydratedDisplayText(group);
|
|
3651
|
+
const itemText = this.pickHydratedDisplayText(item);
|
|
3652
|
+
if (groupText && itemText)
|
|
3653
|
+
return `${groupText}:${itemText}`;
|
|
3654
|
+
return groupText || itemText;
|
|
3655
|
+
}
|
|
3656
|
+
buildHydratedProductOptionString(product) {
|
|
3657
|
+
const segments = [];
|
|
3658
|
+
const sku = (product == null ? void 0 : product.product_sku) || {};
|
|
3659
|
+
if (Array.isArray(sku.variant)) {
|
|
3660
|
+
for (const variant of sku.variant) {
|
|
3661
|
+
const segment = this.formatHydratedNamePair(variant == null ? void 0 : variant.group, variant == null ? void 0 : variant.item);
|
|
3662
|
+
if (segment)
|
|
3663
|
+
segments.push(segment);
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
return segments.join(", ");
|
|
3667
|
+
}
|
|
3668
|
+
normalizeHydratedProductOptionItem(optionItem) {
|
|
3669
|
+
const rawNum = (optionItem == null ? void 0 : optionItem.num) ?? (optionItem == null ? void 0 : optionItem.quantity) ?? 1;
|
|
3670
|
+
const parsedNum = Number(rawNum);
|
|
3671
|
+
const rawPrice = (optionItem == null ? void 0 : optionItem.add_price) ?? (optionItem == null ? void 0 : optionItem.price) ?? 0;
|
|
3672
|
+
const parsedPrice = Number(rawPrice);
|
|
3673
|
+
const normalized = {
|
|
3674
|
+
...optionItem,
|
|
3675
|
+
option_group_item_id: optionItem == null ? void 0 : optionItem.option_group_item_id,
|
|
3676
|
+
option_group_id: optionItem == null ? void 0 : optionItem.option_group_id,
|
|
3677
|
+
num: Number.isFinite(parsedNum) && parsedNum > 0 ? parsedNum : 1,
|
|
3678
|
+
add_price: Number.isFinite(parsedPrice) ? parsedPrice : 0
|
|
3679
|
+
};
|
|
3680
|
+
delete normalized.price;
|
|
3681
|
+
if ((optionItem == null ? void 0 : optionItem.name) !== void 0)
|
|
3682
|
+
normalized.name = optionItem.name;
|
|
3683
|
+
if ((optionItem == null ? void 0 : optionItem.group_name) !== void 0)
|
|
3684
|
+
normalized.group_name = optionItem.group_name;
|
|
3685
|
+
if ((optionItem == null ? void 0 : optionItem.id) !== void 0)
|
|
3686
|
+
normalized.id = optionItem.id;
|
|
3687
|
+
return normalized;
|
|
3688
|
+
}
|
|
1722
3689
|
normalizeHydratedOrderProduct(product) {
|
|
1723
3690
|
const row = { ...product || {} };
|
|
1724
3691
|
if (row.num === void 0 && row.product_quantity !== void 0) {
|
|
1725
3692
|
row.num = row.product_quantity;
|
|
1726
3693
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
3694
|
+
const productSku = (0, import_utils.ensureProductSku)(row);
|
|
3695
|
+
row.product_sku = {
|
|
3696
|
+
...productSku,
|
|
3697
|
+
option: (0, import_utils.normalizeProductSkuOptions)(
|
|
3698
|
+
productSku.option.map(
|
|
3699
|
+
(optionItem) => this.normalizeHydratedProductOptionItem(optionItem || {})
|
|
3700
|
+
)
|
|
3701
|
+
)
|
|
3702
|
+
};
|
|
3703
|
+
delete row[`product_${"option"}_item`];
|
|
1729
3704
|
if (!Array.isArray(row.product_bundle))
|
|
1730
3705
|
row.product_bundle = [];
|
|
1731
3706
|
if (!row.metadata || typeof row.metadata !== "object")
|
|
1732
3707
|
row.metadata = {};
|
|
3708
|
+
if (row.booking_uid && !row.metadata.booking_uid) {
|
|
3709
|
+
row.metadata.booking_uid = row.booking_uid;
|
|
3710
|
+
}
|
|
1733
3711
|
const existingIdentity = row.metadata.unique_identification_number || row.unique_identification_number;
|
|
1734
3712
|
if (!existingIdentity) {
|
|
1735
3713
|
row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
|
|
1736
3714
|
}
|
|
1737
3715
|
const normalized = (0, import_utils3.normalizeOrderProduct)(row);
|
|
3716
|
+
normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
|
|
3717
|
+
normalized.discount_list
|
|
3718
|
+
);
|
|
1738
3719
|
const result = {
|
|
1739
3720
|
...row,
|
|
1740
3721
|
...normalized,
|
|
3722
|
+
product_sku: normalized.product_sku,
|
|
1741
3723
|
metadata: {
|
|
1742
3724
|
...row.metadata,
|
|
1743
3725
|
...normalized.metadata
|
|
@@ -1745,7 +3727,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1745
3727
|
};
|
|
1746
3728
|
if (result.metadata)
|
|
1747
3729
|
delete result.metadata.price_schema_version;
|
|
1748
|
-
return result;
|
|
3730
|
+
return this.sanitizeOrderProductForTempOrder(result);
|
|
1749
3731
|
}
|
|
1750
3732
|
getLastOrderInfo() {
|
|
1751
3733
|
var _a;
|
|
@@ -1754,8 +3736,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1754
3736
|
async getOrderInfo(order_id) {
|
|
1755
3737
|
const res = await this.request.get(`/order/sales/${order_id}`, {
|
|
1756
3738
|
with: ["products", "bookings"]
|
|
1757
|
-
}, {
|
|
1758
|
-
osServer: true
|
|
1759
3739
|
});
|
|
1760
3740
|
return res;
|
|
1761
3741
|
}
|