@pisell/pisellos 2.2.311 → 2.2.312-vm.0
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/apis/picoding.d.ts.map +1 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/effects/index.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/inventory/index.d.ts +92 -0
- package/dist/inventory/index.d.ts.map +1 -0
- package/dist/inventory/index.js +509 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/dataVariant/adapter.d.ts.map +1 -0
- package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts.map +1 -0
- package/dist/model/strategy/adapter/dataVariant/examples.d.ts.map +1 -0
- package/dist/model/strategy/adapter/dataVariant/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/dataVariant/type.d.ts.map +1 -0
- package/dist/model/strategy/adapter/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts.map +1 -0
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts.map +1 -0
- package/dist/model/strategy/adapter/itemRule/examples.d.ts.map +1 -0
- package/dist/model/strategy/adapter/itemRule/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/itemRule/type.d.ts.map +1 -0
- package/dist/model/strategy/adapter/promotion/adapter.d.ts.map +1 -0
- package/dist/model/strategy/adapter/promotion/evaluator.d.ts.map +1 -0
- package/dist/model/strategy/adapter/promotion/examples.d.ts.map +1 -0
- package/dist/model/strategy/adapter/promotion/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/promotion/type.d.ts.map +1 -0
- package/dist/model/strategy/adapter/type.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/example.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/index.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/locales.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/type.d.ts.map +1 -0
- package/dist/model/strategy/adapter/walletPass/utils.d.ts.map +1 -0
- package/dist/model/strategy/engine.d.ts.map +1 -0
- package/dist/model/strategy/index.d.ts.map +1 -0
- package/dist/model/strategy/strategy-example.d.ts.map +1 -0
- package/dist/model/strategy/type.d.ts.map +1 -0
- package/dist/modules/Account/index.d.ts.map +1 -0
- package/dist/modules/Account/types.d.ts.map +1 -0
- package/dist/modules/AccountList/index.d.ts.map +1 -0
- package/dist/modules/AccountList/types.d.ts.map +1 -0
- package/dist/modules/AccountList/utils.d.ts.map +1 -0
- package/dist/modules/BaseModule.d.ts.map +1 -0
- package/dist/modules/BookingContext/index.d.ts.map +1 -0
- package/dist/modules/BookingContext/types.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/flexible.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/formatResourceList.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/index.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/noResource.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/orderLineDisplay.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/productExtend.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/resourceErrors.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/resourceSelection.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/resources.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/serviceTimes.d.ts.map +1 -0
- package/dist/modules/BookingContext/utils/timeSlices.d.ts.map +1 -0
- package/dist/modules/Cart/index.d.ts.map +1 -0
- package/dist/modules/Cart/types.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartAccount.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartDate.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartDiscount.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartNote.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartProduct.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartRelationForms.d.ts.map +1 -0
- package/dist/modules/Cart/utils/cartResource.d.ts.map +1 -0
- package/dist/modules/Cart/utils/changePrice.d.ts.map +1 -0
- package/dist/modules/Cart/utils/index.d.ts.map +1 -0
- package/dist/modules/Customer/constants.d.ts.map +1 -0
- package/dist/modules/Customer/index.d.ts.map +1 -0
- package/dist/modules/Customer/types.d.ts.map +1 -0
- package/dist/modules/Date/index.d.ts.map +1 -0
- package/dist/modules/Date/types.d.ts.map +1 -0
- package/dist/modules/Date/utils.d.ts.map +1 -0
- package/dist/modules/Discount/availability.d.ts.map +1 -0
- package/dist/modules/Discount/entitlementPass.d.ts.map +1 -0
- package/dist/modules/Discount/index.d.ts.map +1 -0
- package/dist/modules/Discount/index.js +1 -0
- package/dist/modules/Discount/types.d.ts.map +1 -0
- package/dist/modules/Guests/index.d.ts.map +1 -0
- package/dist/modules/Guests/types.d.ts.map +1 -0
- package/dist/modules/Holder/index.d.ts.map +1 -0
- package/dist/modules/Holder/types.d.ts.map +1 -0
- package/dist/modules/Holder/utils.d.ts.map +1 -0
- package/dist/modules/OpenData/index.d.ts.map +1 -0
- package/dist/modules/OpenData/types.d.ts.map +1 -0
- package/dist/modules/OpenData/utils.d.ts.map +1 -0
- package/dist/modules/Order/index.d.ts +25 -3
- package/dist/modules/Order/index.d.ts.map +1 -0
- package/dist/modules/Order/index.js +1647 -1211
- package/dist/modules/Order/payment-utils.d.ts.map +1 -0
- package/dist/modules/Order/salesNotes.d.ts.map +1 -0
- package/dist/modules/Order/types.d.ts +7 -0
- package/dist/modules/Order/types.d.ts.map +1 -0
- package/dist/modules/Order/utils/bundleDiscountHydration.d.ts.map +1 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.d.ts.map +1 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.js +2 -2
- package/dist/modules/Order/utils/manualProductDiscount.d.ts.map +1 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts.map +1 -0
- package/dist/modules/Order/utils/productVoucherGroups.d.ts +15 -0
- package/dist/modules/Order/utils/productVoucherGroups.d.ts.map +1 -0
- package/dist/modules/Order/utils/productVoucherGroups.js +115 -0
- package/dist/modules/Order/utils/virtualSettlement.d.ts.map +1 -0
- package/dist/modules/Order/utils/weighedProduct.d.ts.map +1 -0
- package/dist/modules/Order/utils.d.ts.map +1 -0
- package/dist/modules/Payment/cash.d.ts.map +1 -0
- package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts.map +1 -0
- package/dist/modules/Payment/eftpos.d.ts.map +1 -0
- package/dist/modules/Payment/index.d.ts.map +1 -0
- package/dist/modules/Payment/mx51.d.ts.map +1 -0
- package/dist/modules/Payment/types.d.ts.map +1 -0
- package/dist/modules/Payment/utils.d.ts.map +1 -0
- package/dist/modules/Payment/walletpass.d.ts.map +1 -0
- package/dist/modules/Product/index.d.ts.map +1 -0
- package/dist/modules/Product/types.d.ts.map +1 -0
- package/dist/modules/Product/utils.d.ts.map +1 -0
- package/dist/modules/ProductList/clientDataVariants.d.ts.map +1 -0
- package/dist/modules/ProductList/index.d.ts.map +1 -0
- package/dist/modules/ProductList/index.js +33 -12
- package/dist/modules/ProductList/types.d.ts.map +1 -0
- package/dist/modules/Quotation/index.d.ts.map +1 -0
- package/dist/modules/Quotation/types.d.ts.map +1 -0
- package/dist/modules/Resource/index.d.ts.map +1 -0
- package/dist/modules/Resource/types.d.ts.map +1 -0
- package/dist/modules/Resource/utils.d.ts.map +1 -0
- package/dist/modules/ResourcePlanner/index.d.ts.map +1 -0
- package/dist/modules/ResourcePlanner/localClock.d.ts.map +1 -0
- package/dist/modules/ResourcePlanner/planner.d.ts.map +1 -0
- package/dist/modules/ResourcePlanner/types.d.ts.map +1 -0
- package/dist/modules/Rules/index.d.ts +2 -0
- package/dist/modules/Rules/index.d.ts.map +1 -0
- package/dist/modules/Rules/index.js +29 -21
- package/dist/modules/Rules/types.d.ts.map +1 -0
- package/dist/modules/SalesSummary/index.d.ts.map +1 -0
- package/dist/modules/SalesSummary/types.d.ts.map +1 -0
- package/dist/modules/SalesSummary/utils.d.ts.map +1 -0
- package/dist/modules/ScanOrderLogger/index.d.ts.map +1 -0
- package/dist/modules/ScanOrderLogger/providers/feishu.d.ts.map +1 -0
- package/dist/modules/ScanOrderLogger/providers/grafana.d.ts.map +1 -0
- package/dist/modules/ScanOrderLogger/types.d.ts.map +1 -0
- package/dist/modules/Schedule/getDateIsInSchedule.d.ts.map +1 -0
- package/dist/modules/Schedule/index.d.ts.map +1 -0
- package/dist/modules/Schedule/type.d.ts.map +1 -0
- package/dist/modules/Schedule/types.d.ts.map +1 -0
- package/dist/modules/Schedule/utils.d.ts.map +1 -0
- package/dist/modules/Step/index.d.ts.map +1 -0
- package/dist/modules/Step/tyeps.d.ts.map +1 -0
- package/dist/modules/Summary/index.d.ts.map +1 -0
- package/dist/modules/Summary/types.d.ts.map +1 -0
- package/dist/modules/Summary/utils.d.ts.map +1 -0
- package/dist/modules/SurchargeList/index.d.ts.map +1 -0
- package/dist/modules/SurchargeList/types.d.ts.map +1 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/plugins/app.d.ts.map +1 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/request.d.ts.map +1 -0
- package/dist/plugins/shopStore.d.ts.map +1 -0
- package/dist/plugins/user.d.ts.map +1 -0
- package/dist/plugins/window.d.ts.map +1 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/modules/floor-plan/index.d.ts.map +1 -0
- package/dist/server/modules/floor-plan/types.d.ts.map +1 -0
- package/dist/server/modules/index.d.ts.map +1 -0
- package/dist/server/modules/menu/index.d.ts.map +1 -0
- package/dist/server/modules/menu/types.d.ts.map +1 -0
- package/dist/server/modules/order/index.d.ts.map +1 -0
- package/dist/server/modules/order/types.d.ts.map +1 -0
- package/dist/server/modules/order/utils/filterBookings.d.ts.map +1 -0
- package/dist/server/modules/order/utils/filterOrders.d.ts.map +1 -0
- package/dist/server/modules/payment/index.d.ts.map +1 -0
- package/dist/server/modules/payment/types.d.ts.map +1 -0
- package/dist/server/modules/products/index.d.ts.map +1 -0
- package/dist/server/modules/products/types.d.ts.map +1 -0
- package/dist/server/modules/quotation/index.d.ts.map +1 -0
- package/dist/server/modules/quotation/types.d.ts.map +1 -0
- package/dist/server/modules/resource/index.d.ts.map +1 -0
- package/dist/server/modules/resource/types.d.ts.map +1 -0
- package/dist/server/modules/schedule/index.d.ts.map +1 -0
- package/dist/server/modules/schedule/types.d.ts.map +1 -0
- package/dist/server/modules/schedule/utils.d.ts.map +1 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/utils/index.d.ts.map +1 -0
- package/dist/server/utils/product.d.ts.map +1 -0
- package/dist/server/utils/schedule.d.ts.map +1 -0
- package/dist/server/utils/small-ticket.d.ts.map +1 -0
- package/dist/server/utils/time.d.ts.map +1 -0
- package/dist/solution/BaseSales/index.d.ts +16 -1
- package/dist/solution/BaseSales/index.d.ts.map +1 -0
- package/dist/solution/BaseSales/index.js +1363 -1176
- package/dist/solution/BaseSales/types.d.ts.map +1 -0
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts.map +1 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts.map +1 -0
- package/dist/solution/BaseSales/utils/quotationPrice.d.ts.map +1 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts.map +1 -0
- package/dist/solution/BaseSales/utils.d.ts.map +1 -0
- package/dist/solution/BookingByStep/index.d.ts.map +1 -0
- package/dist/solution/BookingByStep/types.d.ts.map +1 -0
- package/dist/solution/BookingByStep/utils/capacity.d.ts.map +1 -0
- package/dist/solution/BookingByStep/utils/products.d.ts.map +1 -0
- package/dist/solution/BookingByStep/utils/resources.d.ts.map +1 -0
- package/dist/solution/BookingByStep/utils/stock.d.ts.map +1 -0
- package/dist/solution/BookingByStep/utils/timeslots.d.ts.map +1 -0
- package/dist/solution/BookingTicket/index.d.ts.map +1 -0
- package/dist/solution/BookingTicket/index.js +198 -108
- package/dist/solution/BookingTicket/types.d.ts +14 -2
- package/dist/solution/BookingTicket/types.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/addProductDecision.js +4 -3
- package/dist/solution/BookingTicket/utils/addTimeAvailability.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/bookingStatus.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/cartView.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/exampleData.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/orderCustomer.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/resolveBestAddTimePlan.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +94 -58
- package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts +10 -0
- package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.js +117 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +1 -0
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +2 -1
- package/dist/solution/BookingTicket/utils/scan/index.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/scanCache.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/sessionCatalogStale.d.ts.map +1 -0
- package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts.map +1 -0
- package/dist/solution/BuyTickets/index.d.ts.map +1 -0
- package/dist/solution/BuyTickets/types.d.ts.map +1 -0
- package/dist/solution/Checkout/index.d.ts.map +1 -0
- package/dist/solution/Checkout/types.d.ts.map +1 -0
- package/dist/solution/Checkout/utils/index.d.ts.map +1 -0
- package/dist/solution/PlaceOrder/index.d.ts.map +1 -0
- package/dist/solution/RegisterAndLogin/config.d.ts.map +1 -0
- package/dist/solution/RegisterAndLogin/index.d.ts.map +1 -0
- package/dist/solution/RegisterAndLogin/types.d.ts.map +1 -0
- package/dist/solution/RegisterAndLogin/utils.d.ts.map +1 -0
- package/dist/solution/Sales/index.d.ts.map +1 -0
- package/dist/solution/Sales/types.d.ts.map +1 -0
- package/dist/solution/ScanOrder/index.d.ts.map +1 -0
- package/dist/solution/ScanOrder/types.d.ts.map +1 -0
- package/dist/solution/ScanOrder/utils.d.ts.map +1 -0
- package/dist/solution/ShopDiscount/index.d.ts.map +1 -0
- package/dist/solution/ShopDiscount/types.d.ts.map +1 -0
- package/dist/solution/ShopDiscount/utils.d.ts.map +1 -0
- package/dist/solution/UnifiedBookingSales/index.d.ts +1 -1
- package/dist/solution/UnifiedBookingSales/index.d.ts.map +1 -0
- package/dist/solution/UnifiedBookingSales/index.js +63 -43
- package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts.map +1 -0
- package/dist/solution/UnifiedBookingSales/types.d.ts.map +1 -0
- package/dist/solution/VenueBooking/index.d.ts.map +1 -0
- package/dist/solution/VenueBooking/types.d.ts.map +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts.map +1 -0
- package/dist/solution/VenueBooking/utils/resource.d.ts.map +1 -0
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts.map +1 -0
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts.map +1 -0
- package/dist/solution/VenueBooking/utils.d.ts.map +1 -0
- package/dist/solution/index.d.ts.map +1 -0
- package/dist/store/createStore.d.ts.map +1 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/os-private-payload.d.ts.map +1 -0
- package/dist/utils/payment-number.d.ts.map +1 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +6 -0
- package/dist/utils/task.d.ts.map +1 -0
- package/dist/utils/watch.d.ts.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +12 -0
- package/lib/inventory/index.d.ts +92 -0
- package/lib/inventory/index.js +287 -0
- package/lib/model/strategy/adapter/promotion/index.js +46 -1
- package/lib/modules/Discount/index.js +1 -0
- package/lib/modules/Order/index.d.ts +25 -3
- package/lib/modules/Order/index.js +145 -11
- package/lib/modules/Order/types.d.ts +7 -0
- package/lib/modules/Order/utils/discountProductLineIdentity.js +1 -1
- package/lib/modules/Order/utils/productVoucherGroups.d.ts +15 -0
- package/lib/modules/Order/utils/productVoucherGroups.js +64 -0
- package/lib/modules/ProductList/index.js +15 -0
- package/lib/modules/Rules/index.d.ts +2 -0
- package/lib/modules/Rules/index.js +6 -0
- package/lib/solution/BaseSales/index.d.ts +16 -1
- package/lib/solution/BaseSales/index.js +89 -9
- package/lib/solution/BookingTicket/index.js +36 -2
- package/lib/solution/BookingTicket/types.d.ts +14 -2
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -3
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +14 -2
- package/lib/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.d.ts +10 -0
- package/lib/solution/BookingTicket/utils/scan/applyProductVoucherCollectionScan.js +71 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +1 -0
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -1
- package/lib/solution/UnifiedBookingSales/index.d.ts +1 -1
- package/lib/solution/UnifiedBookingSales/index.js +14 -3
- package/lib/utils/platform.d.ts +2 -0
- package/lib/utils/platform.js +7 -0
- package/package.json +4 -2
|
@@ -11,6 +11,7 @@ var _utils2 = require("../Product/utils");
|
|
|
11
11
|
var _weighedProduct = require("./utils/weighedProduct");
|
|
12
12
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
13
13
|
var _availability = require("../Discount/availability");
|
|
14
|
+
var _productVoucherGroups = require("./utils/productVoucherGroups");
|
|
14
15
|
var _osPrivatePayload = require("../../utils/os-private-payload");
|
|
15
16
|
var _salesNotes = require("./salesNotes");
|
|
16
17
|
var _paymentUtils = require("./payment-utils");
|
|
@@ -137,6 +138,62 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
137
138
|
rulesHooksOverride;
|
|
138
139
|
moduleHooksOverride;
|
|
139
140
|
orderHooks;
|
|
141
|
+
cartCommandQueue = Promise.resolve();
|
|
142
|
+
queueCartCommand(run) {
|
|
143
|
+
if (!this.orderHooks?.onBeforeCartCommit && !this.store.tempOrder?._extend?.productVoucherGroups?.length) return run();
|
|
144
|
+
const pending = this.cartCommandQueue.then(run, run);
|
|
145
|
+
this.cartCommandQueue = pending.catch(() => undefined);
|
|
146
|
+
return pending;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Use the exact Order normalizers/merge rules on a private draft, not a second projection. */
|
|
150
|
+
beginCartMutation() {
|
|
151
|
+
const current = this.ensureTempOrder();
|
|
152
|
+
const guard = this.orderHooks?.onBeforeCartCommit;
|
|
153
|
+
if (!guard && !current._extend?.productVoucherGroups?.length) return {
|
|
154
|
+
draft: current,
|
|
155
|
+
commit: undefined
|
|
156
|
+
};
|
|
157
|
+
const before = (0, _lodashEs.cloneDeep)(current);
|
|
158
|
+
const draft = (0, _lodashEs.cloneDeep)(current);
|
|
159
|
+
return {
|
|
160
|
+
draft,
|
|
161
|
+
commit: async () => {
|
|
162
|
+
(0, _productVoucherGroups.validateProductVoucherGroups)(draft, this.getDiscountList(), before);
|
|
163
|
+
await guard?.({
|
|
164
|
+
currentItems: (0, _lodashEs.cloneDeep)(before.products),
|
|
165
|
+
proposedItems: (0, _lodashEs.cloneDeep)(draft.products)
|
|
166
|
+
});
|
|
167
|
+
if (this.store.tempOrder !== current || guard !== this.orderHooks?.onBeforeCartCommit || !(0, _lodashEs.isEqual)(current, before)) {
|
|
168
|
+
throw Object.assign(new Error('The cart changed. Please try again.'), {
|
|
169
|
+
code: 'SALES_GUARD_REJECTED'
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
Object.assign(current, draft);
|
|
173
|
+
return current;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Serializes checkout preparation with local cart commands; hydration remains outside this guard. */
|
|
179
|
+
async prepareCheckout(prepare) {
|
|
180
|
+
const run = async () => {
|
|
181
|
+
const order = this.ensureTempOrder();
|
|
182
|
+
(0, _productVoucherGroups.validateProductVoucherGroups)(order, this.getDiscountList(), undefined, true);
|
|
183
|
+
const items = (0, _lodashEs.cloneDeep)(order.products);
|
|
184
|
+
const result = await prepare(items);
|
|
185
|
+
if (this.store.tempOrder !== order || !(0, _lodashEs.isEqual)(order.products, items)) {
|
|
186
|
+
throw Object.assign(new Error('The cart changed. Please try again.'), {
|
|
187
|
+
code: 'SALES_GUARD_REJECTED'
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
(0, _productVoucherGroups.validateProductVoucherGroups)(order, this.getDiscountList(), undefined, true);
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
const pending = this.cartCommandQueue.then(run, run);
|
|
194
|
+
this.cartCommandQueue = pending.catch(() => undefined);
|
|
195
|
+
return pending;
|
|
196
|
+
}
|
|
140
197
|
otherParams;
|
|
141
198
|
// ─── 促销/赠品 ────────────────────────────────────
|
|
142
199
|
/** 评估器引用;由 SalesSdkProvider 注入,未注入时 applyPromotion 静默跳过 */
|
|
@@ -424,8 +481,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
424
481
|
* @example
|
|
425
482
|
* orderModule.updateOtherParams({ cacheId: 'cache-2', channel: 'pos' });
|
|
426
483
|
*/
|
|
427
|
-
updateOtherParams(params) {
|
|
484
|
+
updateOtherParams(params, options) {
|
|
428
485
|
const otherParams = params || {};
|
|
486
|
+
if (options && Object.prototype.hasOwnProperty.call(options, 'hooks')) {
|
|
487
|
+
this.moduleHooksOverride = options.hooks;
|
|
488
|
+
}
|
|
429
489
|
this.syncSessionStorageOptions(otherParams);
|
|
430
490
|
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
431
491
|
this.rulesHooksOverride = otherParams.rules?.hooks;
|
|
@@ -509,6 +569,26 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
509
569
|
hooks: this.rulesHooksOverride || this.createDefaultRulesHooks()
|
|
510
570
|
});
|
|
511
571
|
this.store.rules = rules;
|
|
572
|
+
rules.setDiscountScope((product, discount) => (0, _productVoucherGroups.allowsProductVoucher)(this.store.tempOrder, product, discount));
|
|
573
|
+
}
|
|
574
|
+
setProductVoucherGroups(groups) {
|
|
575
|
+
const order = this.ensureTempOrder();
|
|
576
|
+
const ids = new Set();
|
|
577
|
+
const keys = new Set();
|
|
578
|
+
const known = new Map(this.getDiscountList().map(discount => [String(discount.id), discount]));
|
|
579
|
+
for (const group of groups) {
|
|
580
|
+
if (!group.key || keys.has(group.key)) throw (0, _productVoucherGroups.voucherGroupError)();
|
|
581
|
+
keys.add(group.key);
|
|
582
|
+
for (const id of group.discountIds) {
|
|
583
|
+
const discount = known.get(String(id));
|
|
584
|
+
if (!discount || (discount.tag || discount.type) !== 'good_pass' || ids.has(String(id))) throw (0, _productVoucherGroups.voucherGroupError)();
|
|
585
|
+
ids.add(String(id));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
this.ensureExtend(order).productVoucherGroups = (0, _lodashEs.cloneDeep)(groups);
|
|
589
|
+
}
|
|
590
|
+
validateProductVoucherSelection() {
|
|
591
|
+
(0, _productVoucherGroups.validateProductVoucherGroups)(this.ensureTempOrder(), this.getDiscountList(), undefined, true);
|
|
512
592
|
}
|
|
513
593
|
createDefaultRulesHooks() {
|
|
514
594
|
return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || []);
|
|
@@ -660,7 +740,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
660
740
|
apply: false
|
|
661
741
|
});
|
|
662
742
|
}
|
|
663
|
-
async scanCode(code, customerId) {
|
|
743
|
+
async scanCode(code, customerId, options) {
|
|
664
744
|
if (this.isActiveVirtualSettlementOrder(this.store.tempOrder)) {
|
|
665
745
|
return {
|
|
666
746
|
type: 'clientCalc',
|
|
@@ -671,16 +751,22 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
671
751
|
unavailableReason: _types2.UnavailableReason.ProductNotApplicable
|
|
672
752
|
};
|
|
673
753
|
}
|
|
754
|
+
const scanOrderKey = this.getDiscountConfigOrderIdentityKey(this.store.tempOrder);
|
|
674
755
|
const resultDiscountWithReason = (await this.store.discount?.batchSearch(code, {
|
|
675
756
|
customerId
|
|
676
757
|
})) || {
|
|
677
758
|
discountList: [],
|
|
678
759
|
unavailableReasonKey: null
|
|
679
760
|
};
|
|
761
|
+
if (scanOrderKey !== this.getDiscountConfigOrderIdentityKey(this.store.tempOrder)) {
|
|
762
|
+
throw Object.assign(new Error('The scan session ended.'), {
|
|
763
|
+
code: 'SALES_GUARD_REJECTED'
|
|
764
|
+
});
|
|
765
|
+
}
|
|
680
766
|
const {
|
|
681
|
-
discountList: resultDiscountList,
|
|
682
767
|
unavailableReasonKey
|
|
683
768
|
} = resultDiscountWithReason;
|
|
769
|
+
const resultDiscountList = resultDiscountWithReason.discountList.filter(discount => !options?.productVouchersOnly || (discount.tag || discount.type) === 'good_pass');
|
|
684
770
|
const rulesModule = this.store.rules;
|
|
685
771
|
if (!rulesModule) {
|
|
686
772
|
return {
|
|
@@ -707,7 +793,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
707
793
|
isScan: true
|
|
708
794
|
}));
|
|
709
795
|
const currentSelected = this.getDiscountList().filter(n => n.isSelected);
|
|
710
|
-
if (currentSelected.length && currentSelected.some(n => withScanList.some(m => m.id === n.id))) {
|
|
796
|
+
if (currentSelected.length && (options?.productVouchersOnly ? withScanList.every(scanned => currentSelected.some(selected => selected.id === scanned.id)) : currentSelected.some(n => withScanList.some(m => m.id === n.id)))) {
|
|
711
797
|
await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
|
|
712
798
|
return {
|
|
713
799
|
type: 'clientCalc',
|
|
@@ -2196,8 +2282,12 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2196
2282
|
...existed,
|
|
2197
2283
|
...(origin !== undefined ? {
|
|
2198
2284
|
origin
|
|
2285
|
+
} : {}),
|
|
2286
|
+
...(rawProduct._productVoucherGroupKey ? {
|
|
2287
|
+
productVoucherGroupKey: rawProduct._productVoucherGroupKey
|
|
2199
2288
|
} : {})
|
|
2200
2289
|
};
|
|
2290
|
+
delete normalizedProduct._productVoucherGroupKey;
|
|
2201
2291
|
delete normalizedProduct._origin;
|
|
2202
2292
|
delete normalizedProduct.unique_identification_number;
|
|
2203
2293
|
}
|
|
@@ -3463,6 +3553,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3463
3553
|
const isIncomingCustomItem = productToAdd.metadata?.origin?.isCustomItem === true || productToAdd._origin?.isCustomItem === true;
|
|
3464
3554
|
const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
|
|
3465
3555
|
const matchedIndex = shouldForceNewLine ? -1 : tempOrder.products.findIndex(item => {
|
|
3556
|
+
if ((0, _productVoucherGroups.productVoucherGroupKey)(tempOrder, item) !== productToAdd._productVoucherGroupKey) return false;
|
|
3466
3557
|
if (this.hasGoodPassDiscount(item)) return false;
|
|
3467
3558
|
const isRuntimeEntitlementPass = this.isRuntimeEntitlementAppend(item, tempOrder);
|
|
3468
3559
|
if (isIncomingEntitlementAppend !== isRuntimeEntitlementPass) {
|
|
@@ -3642,7 +3733,18 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3642
3733
|
* // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
|
|
3643
3734
|
*/
|
|
3644
3735
|
async addProductToOrder(product, booking, options) {
|
|
3645
|
-
|
|
3736
|
+
return this.queueCartCommand(() => this.addProductToOrderDraft(product, booking, options));
|
|
3737
|
+
}
|
|
3738
|
+
async addProductToOrderDraft(product, booking, options) {
|
|
3739
|
+
const mutation = this.beginCartMutation();
|
|
3740
|
+
let tempOrder = mutation.draft;
|
|
3741
|
+
if (options?.productVoucherGroupKey) {
|
|
3742
|
+
if (!tempOrder._extend?.productVoucherGroups?.some(group => group.key === options.productVoucherGroupKey)) throw (0, _productVoucherGroups.voucherGroupError)();
|
|
3743
|
+
product = {
|
|
3744
|
+
...product,
|
|
3745
|
+
_productVoucherGroupKey: options.productVoucherGroupKey
|
|
3746
|
+
};
|
|
3747
|
+
}
|
|
3646
3748
|
const salesNoteDrafts = (options?.salesNotes || []).map(draft => ({
|
|
3647
3749
|
note_type: String(draft.note_type || '').trim(),
|
|
3648
3750
|
text: {
|
|
@@ -3736,6 +3838,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3736
3838
|
rollbackProductAndNotesMutation();
|
|
3737
3839
|
throw error;
|
|
3738
3840
|
}
|
|
3841
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
3739
3842
|
await this.finalizeProductOrderMutation(tempOrder);
|
|
3740
3843
|
this.logInfo('addProductToOrder success', {
|
|
3741
3844
|
product_id: product.product_id,
|
|
@@ -3754,7 +3857,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3754
3857
|
* ]);
|
|
3755
3858
|
*/
|
|
3756
3859
|
async addProductsToOrder(items, options) {
|
|
3757
|
-
|
|
3860
|
+
return this.queueCartCommand(() => this.addProductsToOrderDraft(items, options));
|
|
3861
|
+
}
|
|
3862
|
+
async addProductsToOrderDraft(items, options) {
|
|
3863
|
+
const mutation = this.beginCartMutation();
|
|
3864
|
+
let tempOrder = mutation.draft;
|
|
3758
3865
|
if (!Array.isArray(items) || items.length === 0) return tempOrder.products;
|
|
3759
3866
|
for (const item of items || []) {
|
|
3760
3867
|
const {
|
|
@@ -3777,6 +3884,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3777
3884
|
const appendResult = this.appendProductLineToTempOrder(tempOrder, product, booking);
|
|
3778
3885
|
if (appendResult) await appendResult;
|
|
3779
3886
|
}
|
|
3887
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
3780
3888
|
await this.finalizeProductOrderMutation(tempOrder, options);
|
|
3781
3889
|
this.logInfo('addProductsToOrder success', {
|
|
3782
3890
|
itemsCount: items.length
|
|
@@ -4109,9 +4217,14 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4109
4217
|
return tempOrder.products[productIndex].metadata?.unique_identification_number;
|
|
4110
4218
|
}
|
|
4111
4219
|
async updateOrderProduct(params) {
|
|
4112
|
-
|
|
4220
|
+
return this.queueCartCommand(() => this.updateOrderProductDraft(params));
|
|
4221
|
+
}
|
|
4222
|
+
async updateOrderProductDraft(params) {
|
|
4223
|
+
const mutation = this.beginCartMutation();
|
|
4224
|
+
let tempOrder = mutation.draft;
|
|
4113
4225
|
const reapplyWeighedDiscountProductUids = [];
|
|
4114
4226
|
const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params, reapplyWeighedDiscountProductUids);
|
|
4227
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
4115
4228
|
const promotionPayload = await this.evaluatePromotion();
|
|
4116
4229
|
this.applyDiscount({
|
|
4117
4230
|
reapplyWeighedDiscountProductUids,
|
|
@@ -4129,7 +4242,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4129
4242
|
return tempOrder.products;
|
|
4130
4243
|
}
|
|
4131
4244
|
async updateOrderProducts(paramsList) {
|
|
4132
|
-
|
|
4245
|
+
return this.queueCartCommand(() => this.updateOrderProductsDraft(paramsList));
|
|
4246
|
+
}
|
|
4247
|
+
async updateOrderProductsDraft(paramsList) {
|
|
4248
|
+
const mutation = this.beginCartMutation();
|
|
4249
|
+
let tempOrder = mutation.draft;
|
|
4133
4250
|
if (!paramsList.length) {
|
|
4134
4251
|
return tempOrder.products;
|
|
4135
4252
|
}
|
|
@@ -4142,6 +4259,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4142
4259
|
}
|
|
4143
4260
|
return acc;
|
|
4144
4261
|
}, []);
|
|
4262
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
4145
4263
|
await this.finalizeAfterProductsMutation(tempOrder, {
|
|
4146
4264
|
reapplyWeighedDiscountProductUids,
|
|
4147
4265
|
reapplyBookingDiscountProductUids: reapplyBookingDiscountProductUids.length ? reapplyBookingDiscountProductUids : undefined
|
|
@@ -4152,6 +4270,9 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4152
4270
|
return tempOrder.products;
|
|
4153
4271
|
}
|
|
4154
4272
|
async updateOrderProductQuantity(params) {
|
|
4273
|
+
return this.queueCartCommand(() => this.updateOrderProductQuantityDraft(params));
|
|
4274
|
+
}
|
|
4275
|
+
async updateOrderProductQuantityDraft(params) {
|
|
4155
4276
|
const {
|
|
4156
4277
|
product_id,
|
|
4157
4278
|
product_variant_id,
|
|
@@ -4161,7 +4282,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4161
4282
|
product_sku,
|
|
4162
4283
|
product_bundle
|
|
4163
4284
|
} = params;
|
|
4164
|
-
const
|
|
4285
|
+
const mutation = this.beginCartMutation();
|
|
4286
|
+
let tempOrder = mutation.draft;
|
|
4165
4287
|
this.repairDuplicateProductLineIdentities(tempOrder);
|
|
4166
4288
|
const identityLookup = {
|
|
4167
4289
|
product_id,
|
|
@@ -4218,6 +4340,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4218
4340
|
}
|
|
4219
4341
|
}
|
|
4220
4342
|
tempOrder.products[productIndex] = normalizedProduct;
|
|
4343
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
4221
4344
|
this.prepareVirtualSettlementTempOrder(tempOrder);
|
|
4222
4345
|
const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder);
|
|
4223
4346
|
const promotionPayload = !isVirtualSettlement ? await this.evaluatePromotion() : null;
|
|
@@ -4294,7 +4417,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4294
4417
|
* await order.removeProductsFromOrder([identityA, identityB]);
|
|
4295
4418
|
*/
|
|
4296
4419
|
async removeProductsFromOrder(identities, options) {
|
|
4297
|
-
|
|
4420
|
+
return this.queueCartCommand(() => this.removeProductsFromOrderDraft(identities, options));
|
|
4421
|
+
}
|
|
4422
|
+
async removeProductsFromOrderDraft(identities, options) {
|
|
4423
|
+
const mutation = this.beginCartMutation();
|
|
4424
|
+
let tempOrder = mutation.draft;
|
|
4298
4425
|
if (!identities.length) {
|
|
4299
4426
|
return tempOrder.products;
|
|
4300
4427
|
}
|
|
@@ -4361,6 +4488,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4361
4488
|
}
|
|
4362
4489
|
}
|
|
4363
4490
|
this.removeSalesNotesForMissingProductLines(tempOrder);
|
|
4491
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
4364
4492
|
await this.finalizeAfterProductsMutation(tempOrder);
|
|
4365
4493
|
this.logInfo('removeProductsFromOrder success', {
|
|
4366
4494
|
identities
|
|
@@ -4376,7 +4504,11 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4376
4504
|
* 普通整单 note 保持不变;以商品行为主体的 Sales Notes 同步删除。
|
|
4377
4505
|
*/
|
|
4378
4506
|
async clearOrderCartLines() {
|
|
4379
|
-
|
|
4507
|
+
return this.queueCartCommand(() => this.clearOrderCartLinesDraft());
|
|
4508
|
+
}
|
|
4509
|
+
async clearOrderCartLinesDraft() {
|
|
4510
|
+
const mutation = this.beginCartMutation();
|
|
4511
|
+
let tempOrder = mutation.draft;
|
|
4380
4512
|
this.ensureSalesNotesLoadedForMutation(tempOrder);
|
|
4381
4513
|
tempOrder.products = [];
|
|
4382
4514
|
tempOrder.bookings = [];
|
|
@@ -4389,6 +4521,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4389
4521
|
productsByUid: {}
|
|
4390
4522
|
};
|
|
4391
4523
|
}
|
|
4524
|
+
if (mutation.commit) tempOrder = await mutation.commit();
|
|
4392
4525
|
const promotionPayload = await this.evaluatePromotion();
|
|
4393
4526
|
this.applyDiscount();
|
|
4394
4527
|
this.sanitizeTempOrderProducts(tempOrder);
|
|
@@ -4525,6 +4658,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
4525
4658
|
}
|
|
4526
4659
|
async runSubmitTempOrder(params) {
|
|
4527
4660
|
const tempOrder = this.ensureTempOrder();
|
|
4661
|
+
(0, _productVoucherGroups.validateProductVoucherGroups)(tempOrder, this.getDiscountList(), undefined, true);
|
|
4528
4662
|
this.prepareVirtualSettlementTempOrder(tempOrder);
|
|
4529
4663
|
const isOnlineStorePlatform = this.isOnlineStorePlatform();
|
|
4530
4664
|
const shouldConfirmPendingVoucherPayments = params?.confirmPendingVoucherPayments !== false;
|
|
@@ -438,6 +438,8 @@ export type AddProductBookingInput = Record<string, any>;
|
|
|
438
438
|
* 避免步进器修改数量改变该组展示位置。
|
|
439
439
|
*/
|
|
440
440
|
export interface AddProductToOrderOptions {
|
|
441
|
+
/** Associates a selection with an existing runtime voucher group. */
|
|
442
|
+
productVoucherGroupKey?: string;
|
|
441
443
|
insertAfterProductUid?: string;
|
|
442
444
|
/** 跳过同商品/规格匹配,始终新增购物车行。 */
|
|
443
445
|
disableMerge?: boolean;
|
|
@@ -517,6 +519,11 @@ export type OrderProductMergeDecisionResult = boolean | {
|
|
|
517
519
|
[key: string]: any;
|
|
518
520
|
};
|
|
519
521
|
export interface OrderHooksConfig {
|
|
522
|
+
/** Awaited before a local cart draft is published. Reject to leave the live order unchanged. */
|
|
523
|
+
onBeforeCartCommit?: (context: {
|
|
524
|
+
currentItems: readonly OrderProduct[];
|
|
525
|
+
proposedItems: readonly OrderProduct[];
|
|
526
|
+
}) => void | Promise<void>;
|
|
520
527
|
onBeforeMergeProductToOrder?: (context: OrderProductMergeDecisionContext) => OrderProductMergeDecisionResult | Promise<OrderProductMergeDecisionResult>;
|
|
521
528
|
}
|
|
522
529
|
/**
|
|
@@ -192,7 +192,7 @@ function consolidateDiscountFreeProductLines(tempOrder) {
|
|
|
192
192
|
bundle_selling_price: String(bundle?.bundle_selling_price ?? '')
|
|
193
193
|
}))
|
|
194
194
|
});
|
|
195
|
-
const mergeKey = [discountSplitOriginUid, product.product_id, product.product_variant_id ?? 0, fingerprint, priceSignature].join('#');
|
|
195
|
+
const mergeKey = [discountSplitOriginUid, productUid ? tempOrder._extend?.productsByUid?.[productUid]?.productVoucherGroupKey ?? '' : '', product.product_id, product.product_variant_id ?? 0, fingerprint, priceSignature].join('#');
|
|
196
196
|
const matchedIndex = productIndexByKey.get(mergeKey);
|
|
197
197
|
|
|
198
198
|
// 当前拆分来源 + 商品结构组合第一次出现时,保留该行作为回并目标。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Discount } from '../../Discount/types';
|
|
2
|
+
import type { OrderTempOrder } from '../types';
|
|
3
|
+
/** Runtime-only allocation constraints. Never copied into order/product metadata. */
|
|
4
|
+
export interface ProductVoucherGroup {
|
|
5
|
+
key: string;
|
|
6
|
+
discountIds: Array<number | string>;
|
|
7
|
+
}
|
|
8
|
+
export declare function productVoucherGroupKey(order: OrderTempOrder, product: any): string | undefined;
|
|
9
|
+
export declare function isUsableProductVoucher(discount: Discount): boolean;
|
|
10
|
+
export declare function voucherGroupError(): Error & {
|
|
11
|
+
code: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function allowsProductVoucher(order: OrderTempOrder | null | undefined, product: any, discount: Discount): boolean;
|
|
14
|
+
/** Reductions stay possible when a voucher expires; checkout always requires full coverage. */
|
|
15
|
+
export declare function validateProductVoucherGroups(order: OrderTempOrder, discounts: Discount[], previous?: OrderTempOrder, requireCoverage?: boolean): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.allowsProductVoucher = allowsProductVoucher;
|
|
7
|
+
exports.isUsableProductVoucher = isUsableProductVoucher;
|
|
8
|
+
exports.productVoucherGroupKey = productVoucherGroupKey;
|
|
9
|
+
exports.validateProductVoucherGroups = validateProductVoucherGroups;
|
|
10
|
+
exports.voucherGroupError = voucherGroupError;
|
|
11
|
+
var _availability = require("../../Discount/availability");
|
|
12
|
+
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
13
|
+
var _utils = require("../../../solution/ShopDiscount/utils");
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
/** Runtime-only allocation constraints. Never copied into order/product metadata. */
|
|
16
|
+
|
|
17
|
+
function productVoucherGroupKey(order, product) {
|
|
18
|
+
const uid = product?.metadata?.unique_identification_number ?? product?.unique_identification_number;
|
|
19
|
+
return order._extend?.productsByUid?.[String(uid)]?.productVoucherGroupKey;
|
|
20
|
+
}
|
|
21
|
+
function isUsableProductVoucher(discount) {
|
|
22
|
+
return (discount.tag || discount.type) === 'good_pass' && !discount.isEditMode && !discount.isDisabled && !(0, _availability.getDiscountUsageBlockReason)(discount) && !(0, _utils.getDiscountTimeUnavailableReason)(discount, (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss'));
|
|
23
|
+
}
|
|
24
|
+
function voucherGroupError() {
|
|
25
|
+
return Object.assign(new Error('The selected items no longer match the available vouchers. Please adjust your selection.'), {
|
|
26
|
+
code: 'PRODUCT_VOUCHER_GROUP_INVALID'
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function allowsProductVoucher(order, product, discount) {
|
|
30
|
+
const groups = order?._extend?.productVoucherGroups;
|
|
31
|
+
if (!order || !groups?.length) return true;
|
|
32
|
+
const key = productVoucherGroupKey(order, product);
|
|
33
|
+
if (!key) return !groups.some(group => group.discountIds.some(id => String(id) === String(discount.id)));
|
|
34
|
+
return (discount.tag || discount.type) === 'good_pass' && Boolean(groups.find(group => group.key === key)?.discountIds.some(id => String(id) === String(discount.id)));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Reductions stay possible when a voucher expires; checkout always requires full coverage. */
|
|
38
|
+
function validateProductVoucherGroups(order, discounts, previous, requireCoverage = false) {
|
|
39
|
+
const groups = order._extend?.productVoucherGroups;
|
|
40
|
+
if (!groups?.length) return;
|
|
41
|
+
const usedIds = new Set();
|
|
42
|
+
const byId = new Map(discounts.filter(isUsableProductVoucher).map(discount => [String(discount.id), discount]));
|
|
43
|
+
const quantity = item => Number(item.num ?? item.product_quantity ?? 0);
|
|
44
|
+
for (const group of groups) {
|
|
45
|
+
const items = order.products.filter(item => productVoucherGroupKey(order, item) === group.key);
|
|
46
|
+
const selected = items.reduce((sum, item) => sum + quantity(item), 0);
|
|
47
|
+
const before = previous?.products.filter(item => productVoucherGroupKey(previous, item) === group.key).reduce((sum, item) => sum + quantity(item), 0) ?? 0;
|
|
48
|
+
if (!requireCoverage && previous && selected <= before) continue;
|
|
49
|
+
const ids = new Set(group.discountIds.map(String).filter(id => byId.has(id)));
|
|
50
|
+
if (!Number.isInteger(selected) || selected < 0 || selected > ids.size) throw voucherGroupError();
|
|
51
|
+
if (!requireCoverage) continue;
|
|
52
|
+
for (const item of items) {
|
|
53
|
+
const applied = (item.discount_list || []).filter(entry => (entry.type || entry.tag) === 'good_pass');
|
|
54
|
+
// Rules splits a good_pass allocation into one physical line per instance.
|
|
55
|
+
const id = String(applied[0]?.discount?.resource_id ?? '');
|
|
56
|
+
const voucher = byId.get(id);
|
|
57
|
+
if (quantity(item) !== 1 || applied.length !== 1 || !ids.has(id) || !voucher?.isAvailable || voucher.config?.isAvailable === false || usedIds.has(id)) throw voucherGroupError();
|
|
58
|
+
usedIds.add(id);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (order.products.some(item => !groups.some(group => group.key === productVoucherGroupKey(order, item)))) {
|
|
62
|
+
throw voucherGroupError();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -66,7 +66,13 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
66
66
|
* productList.updateOtherParams({ channel: 'pos' });
|
|
67
67
|
*/
|
|
68
68
|
updateOtherParams(params) {
|
|
69
|
+
const previousScope = this.otherParams.catalogScopeKey;
|
|
69
70
|
this.otherParams = params || {};
|
|
71
|
+
if (previousScope !== this.otherParams.catalogScopeKey && (previousScope || this.otherParams.catalogScopeKey)) {
|
|
72
|
+
this.store.list = [];
|
|
73
|
+
this.rawProductPriceSources.clear();
|
|
74
|
+
this.core.effects.emit(`${this.name}:changed`, this.store.list);
|
|
75
|
+
}
|
|
70
76
|
}
|
|
71
77
|
async storeChange(path, value) {
|
|
72
78
|
// No longer needed - products are stored as plain objects instead of Product instances
|
|
@@ -101,6 +107,12 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
101
107
|
status = 'published',
|
|
102
108
|
strategy_context
|
|
103
109
|
} = {}, options) {
|
|
110
|
+
const scope = this.otherParams.catalogScopeKey;
|
|
111
|
+
const assertScope = () => {
|
|
112
|
+
if (scope !== this.otherParams.catalogScopeKey) throw Object.assign(new Error('Product catalog context changed'), {
|
|
113
|
+
name: 'AbortError'
|
|
114
|
+
});
|
|
115
|
+
};
|
|
104
116
|
// // 如果 schedule_ids 为空,则需要尝试从 schedule 模块里获取
|
|
105
117
|
// if (!schedule_ids?.length) {
|
|
106
118
|
// const schedule_ids_data = this.store.schedule
|
|
@@ -180,6 +192,7 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
180
192
|
const handledByOsServer = (0, _clientDataVariants.isProductQueryHandledByOsServer)(this.core, this.request);
|
|
181
193
|
const originalCallback = options?.callback;
|
|
182
194
|
const subscriptionCallback = typeof originalCallback === 'function' ? async result => {
|
|
195
|
+
if (scope !== this.otherParams.catalogScopeKey) return;
|
|
183
196
|
const callbackList = result?.data?.list;
|
|
184
197
|
if (!Array.isArray(callbackList)) {
|
|
185
198
|
originalCallback(result);
|
|
@@ -197,6 +210,7 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
197
210
|
queryPayload,
|
|
198
211
|
handledByOsServer
|
|
199
212
|
});
|
|
213
|
+
assertScope();
|
|
200
214
|
await this.addProduct(products);
|
|
201
215
|
originalCallback(handledByOsServer ? result : {
|
|
202
216
|
...result,
|
|
@@ -212,6 +226,7 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
212
226
|
subscriberId: options?.subscriberId,
|
|
213
227
|
customToast: () => {}
|
|
214
228
|
});
|
|
229
|
+
assertScope();
|
|
215
230
|
if (!handledByOsServer && Array.isArray(productsData.data.list)) {
|
|
216
231
|
this.replaceRawProductQueryResult(productsData.data.list, product_ids);
|
|
217
232
|
}
|
|
@@ -9,6 +9,8 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
9
9
|
private store;
|
|
10
10
|
window: WindowPlugin;
|
|
11
11
|
private hooks;
|
|
12
|
+
private discountScope?;
|
|
13
|
+
setDiscountScope(scope: (product: any, discount: Discount) => boolean): void;
|
|
12
14
|
constructor(name?: string, version?: string);
|
|
13
15
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
14
16
|
setRulesList(rulesList: Rules[]): Promise<void>;
|
|
@@ -20,6 +20,10 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
20
20
|
store;
|
|
21
21
|
window; // WindowPlugin 实例
|
|
22
22
|
hooks;
|
|
23
|
+
discountScope;
|
|
24
|
+
setDiscountScope(scope) {
|
|
25
|
+
this.discountScope = scope;
|
|
26
|
+
}
|
|
23
27
|
constructor(name, version) {
|
|
24
28
|
super(name, version);
|
|
25
29
|
this.hooks = {};
|
|
@@ -722,6 +726,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
722
726
|
|
|
723
727
|
// 辅助函数:检查商品是否对某个折扣卡可用
|
|
724
728
|
const checkItemApplicableForDiscount = (flatItem, discount) => {
|
|
729
|
+
if (this.discountScope && !this.discountScope(flatItem.originProduct, discount)) return false;
|
|
725
730
|
if (discount.config?.isAvailable === false) return false;
|
|
726
731
|
let product;
|
|
727
732
|
if (flatItem.type === 'main') {
|
|
@@ -1093,6 +1098,7 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1093
1098
|
|
|
1094
1099
|
// 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
|
|
1095
1100
|
const applicableDiscounts = sortedDiscountList.filter(discount => {
|
|
1101
|
+
if (this.discountScope && !this.discountScope(originProduct, discount)) return false;
|
|
1096
1102
|
if (this.isItemRewardProductDiscount(product)) return false;
|
|
1097
1103
|
// 🔥 检查策略可用性(针对全额抵扣卡和折扣卡)
|
|
1098
1104
|
const discountType = discount.tag || discount.type;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InventoryController, type CheckoutRuntimeSnapshot } from '../../inventory';
|
|
1
2
|
import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
2
3
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
4
|
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentOptions, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
@@ -47,6 +48,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
47
48
|
protected appPlugin: AppPlugin;
|
|
48
49
|
protected store: BaseSalesState;
|
|
49
50
|
protected otherParams: Record<string, any>;
|
|
51
|
+
getInventory(): InventoryController | undefined;
|
|
52
|
+
prepareCheckout(signal?: AbortSignal): Promise<CheckoutRuntimeSnapshot | undefined>;
|
|
50
53
|
protected cacheId: string | undefined;
|
|
51
54
|
/**
|
|
52
55
|
* 由已在初始化阶段解析过设备短号的业务解决方案写入。
|
|
@@ -166,6 +169,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
166
169
|
* 可覆盖此方法并把未识别的 name 委托给 `super.createSubModule(name)`。
|
|
167
170
|
*/
|
|
168
171
|
protected createSubModule(moduleName: string): Module | null;
|
|
172
|
+
private inventoryOrderHooks?;
|
|
169
173
|
protected getSubModuleHooks(moduleName: string): any;
|
|
170
174
|
/**
|
|
171
175
|
* 构造传给 BaseSales 子模块的完整运行态参数,保证初始化和后续同步语义一致。
|
|
@@ -203,7 +207,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
203
207
|
private isActiveVirtualSettlementOrder;
|
|
204
208
|
private isHistoricalVirtualSettlementOrder;
|
|
205
209
|
private syncAppDataToTempOrder;
|
|
210
|
+
private initialization?;
|
|
211
|
+
/** Hosts can await readiness without changing Core's synchronous registration API. */
|
|
212
|
+
whenInitialized(): Promise<void>;
|
|
206
213
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
214
|
+
private initializeSalesRuntime;
|
|
207
215
|
destroy(): Promise<void>;
|
|
208
216
|
/**
|
|
209
217
|
* 加载销售订单到统一 tempOrder 工作区。
|
|
@@ -306,7 +314,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
306
314
|
discountList: Discount[];
|
|
307
315
|
originalDiscountList?: Discount[];
|
|
308
316
|
}): Promise<void>;
|
|
309
|
-
scanPromotionCode(code: string, customerId?: number
|
|
317
|
+
scanPromotionCode(code: string, customerId?: number, options?: {
|
|
318
|
+
productVouchersOnly?: boolean;
|
|
319
|
+
}): Promise<BaseSalesScanCodeResult>;
|
|
310
320
|
setDiscountSelected(params: {
|
|
311
321
|
discountId: number;
|
|
312
322
|
isSelected: boolean;
|
|
@@ -498,6 +508,11 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
498
508
|
private hasSmartPricingStrategies;
|
|
499
509
|
shouldRecalculateProductBookingPricesForContextChange(params: BaseSalesPriceRecalculationContextChange): boolean;
|
|
500
510
|
calculateProductBookingPrices(paramsList: BaseSalesCalculateProductBookingPriceParams[]): Promise<BaseSalesProductBookingPriceResult[]>;
|
|
511
|
+
setProductVoucherGroups(groups: Array<{
|
|
512
|
+
key: string;
|
|
513
|
+
discountIds: Array<number | string>;
|
|
514
|
+
}>): void;
|
|
515
|
+
validateProductVoucherSelection(): void;
|
|
501
516
|
addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
502
517
|
updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
|
|
503
518
|
updateOrderProducts(paramsList: UpdateOrderProductParams[]): Promise<import("../../modules/Order/types").OrderProduct[]>;
|