@pisell/pisellos 2.2.314 → 2.2.316
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/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
- package/dist/model/strategy/adapter/itemRule/adapter.js +74 -7
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
- package/dist/model/strategy/adapter/itemRule/evaluator.js +13 -0
- package/dist/model/strategy/adapter/itemRule/type.d.ts +40 -1
- package/dist/model/strategy/adapter/itemRule/type.js +10 -0
- package/dist/model/strategy/adapter/promotion/evaluator.js +89 -104
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +28 -4
- package/dist/modules/BookingContext/utils/productExtend.d.ts +7 -0
- package/dist/modules/BookingContext/utils/productExtend.js +62 -18
- package/dist/modules/BookingContext/utils/resources.js +1 -1
- package/dist/modules/BusinessAvailability/index.d.ts +30 -0
- package/dist/modules/BusinessAvailability/index.js +204 -0
- package/dist/modules/Cart/index.js +4 -3
- package/dist/modules/Cart/types.d.ts +2 -0
- package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
- package/dist/modules/Cart/utils/cartProduct.js +59 -32
- package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
- package/dist/modules/FulfillmentTiming/index.js +407 -0
- package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
- package/dist/modules/FulfillmentTiming/types.js +1 -0
- package/dist/modules/Holder/utils.d.ts +2 -0
- package/dist/modules/Holder/utils.js +32 -2
- package/dist/modules/OpenData/contactInfo.d.ts +20 -0
- package/dist/modules/OpenData/contactInfo.js +70 -0
- package/dist/modules/OpenData/index.d.ts +1 -0
- package/dist/modules/OpenData/index.js +1 -0
- package/dist/modules/OpenData/types.d.ts +23 -0
- package/dist/modules/Order/holderRelations.d.ts +14 -0
- package/dist/modules/Order/holderRelations.js +154 -0
- package/dist/modules/Order/index.d.ts +16 -4
- package/dist/modules/Order/index.js +926 -511
- package/dist/modules/Order/localEftposState.d.ts +13 -0
- package/dist/modules/Order/localEftposState.js +39 -0
- package/dist/modules/Order/pickupTiming.d.ts +46 -0
- package/dist/modules/Order/pickupTiming.js +53 -0
- package/dist/modules/Order/types.d.ts +49 -3
- package/dist/modules/Order/types.js +2 -0
- package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/dist/modules/Order/utils/discountProductLineIdentity.js +142 -7
- package/dist/modules/Order/utils/orderCollectionIdentity.js +24 -10
- package/dist/modules/Order/utils.d.ts +2 -1
- package/dist/modules/Order/utils.js +61 -17
- package/dist/modules/Payment/index.js +9 -10
- package/dist/modules/Product/types.d.ts +11 -0
- package/dist/modules/ProductList/index.js +1 -1
- package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
- package/dist/modules/ResourcePlanner/planner.js +332 -23
- package/dist/modules/ResourcePlanner/types.d.ts +29 -0
- package/dist/modules/Rules/index.js +62 -61
- package/dist/modules/Schedule/index.d.ts +8 -0
- package/dist/modules/Schedule/index.js +141 -39
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/plugins/request.d.ts +7 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1557 -1322
- package/dist/server/modules/form/index.d.ts +19 -0
- package/dist/server/modules/form/index.js +205 -0
- package/dist/server/modules/form/types.d.ts +13 -0
- package/dist/server/modules/form/types.js +3 -0
- package/dist/server/modules/index.d.ts +3 -0
- package/dist/server/modules/index.js +4 -0
- package/dist/server/modules/order/index.d.ts +19 -0
- package/dist/server/modules/order/index.js +1071 -774
- package/dist/server/modules/order/types.d.ts +4 -0
- package/dist/server/modules/products/index.d.ts +28 -7
- package/dist/server/modules/products/index.js +1297 -770
- package/dist/server/modules/products/replication.d.ts +8 -0
- package/dist/server/modules/products/replication.js +69 -0
- package/dist/server/modules/products/types.d.ts +12 -1
- package/dist/server/modules/products/types.js +4 -0
- package/dist/server/test.json +1 -1
- package/dist/server/utils/small-ticket.d.ts +1 -85
- package/dist/server/utils/small-ticket.js +2 -2542
- package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
- package/dist/shared/payment/loadPaymentMethods.js +66 -0
- package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
- package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
- package/dist/shared/receipt/small-ticket.d.ts +96 -0
- package/dist/shared/receipt/small-ticket.js +2763 -0
- package/dist/shared/receipt/templateVisibility.d.ts +26 -0
- package/dist/shared/receipt/templateVisibility.js +68 -0
- package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
- package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
- package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
- package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
- package/dist/solution/BaseSales/index.d.ts +43 -16
- package/dist/solution/BaseSales/index.js +2028 -1247
- package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
- package/dist/solution/BaseSales/pickupTiming.js +616 -0
- package/dist/solution/BaseSales/types.d.ts +12 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +10 -3
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -4
- package/dist/solution/BookingByStep/index.d.ts +4 -2
- package/dist/solution/BookingByStep/index.js +8 -3
- package/dist/solution/BookingTicket/index.d.ts +23 -3
- package/dist/solution/BookingTicket/index.js +867 -507
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
- package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
- package/dist/solution/BookingTicket/utils/cartView.js +3 -1
- package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
- package/dist/solution/OrderInvoicePreview/index.js +340 -0
- package/dist/solution/RegisterAndLogin/config.js +54 -11
- package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
- package/dist/solution/RegisterAndLogin/index.js +1 -1
- package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/dist/solution/RegisterAndLogin/utils.js +36 -16
- package/dist/solution/ScanOrder/index.js +65 -31
- package/dist/solution/ScanOrder/types.d.ts +3 -0
- package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
- package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
- package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
- package/dist/solution/UnifiedBookingSales/index.js +1715 -906
- package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
- package/dist/solution/VenueBooking/index.d.ts +15 -2
- package/dist/solution/VenueBooking/index.js +1062 -785
- package/dist/solution/VenueBooking/types.d.ts +2 -1
- package/dist/solution/VenueBooking/types.js +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
- package/dist/solution/index.d.ts +1 -0
- package/dist/solution/index.js +2 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +21 -1
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
- package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
- package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
- package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
- package/lib/model/strategy/adapter/itemRule/type.js +10 -0
- package/lib/model/strategy/adapter/promotion/evaluator.js +9 -14
- package/lib/model/strategy/adapter/promotion/index.js +46 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +17 -1
- package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
- package/lib/modules/BookingContext/utils/productExtend.js +45 -2
- package/lib/modules/BookingContext/utils/resources.js +1 -1
- package/lib/modules/BusinessAvailability/index.d.ts +30 -0
- package/lib/modules/BusinessAvailability/index.js +146 -0
- package/lib/modules/Cart/index.js +4 -2
- package/lib/modules/Cart/types.d.ts +2 -0
- package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
- package/lib/modules/Cart/utils/cartProduct.js +39 -20
- package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
- package/lib/modules/FulfillmentTiming/index.js +359 -0
- package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
- package/lib/modules/FulfillmentTiming/types.js +5 -0
- package/lib/modules/Holder/utils.d.ts +2 -0
- package/lib/modules/Holder/utils.js +27 -1
- package/lib/modules/OpenData/contactInfo.d.ts +20 -0
- package/lib/modules/OpenData/contactInfo.js +56 -0
- package/lib/modules/OpenData/index.d.ts +1 -0
- package/lib/modules/OpenData/index.js +12 -0
- package/lib/modules/OpenData/types.d.ts +23 -0
- package/lib/modules/Order/holderRelations.d.ts +14 -0
- package/lib/modules/Order/holderRelations.js +98 -0
- package/lib/modules/Order/index.d.ts +16 -4
- package/lib/modules/Order/index.js +284 -50
- package/lib/modules/Order/localEftposState.d.ts +13 -0
- package/lib/modules/Order/localEftposState.js +44 -0
- package/lib/modules/Order/pickupTiming.d.ts +46 -0
- package/lib/modules/Order/pickupTiming.js +61 -0
- package/lib/modules/Order/types.d.ts +49 -3
- package/lib/modules/Order/types.js +1 -0
- package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
- package/lib/modules/Order/utils/discountProductLineIdentity.js +51 -2
- package/lib/modules/Order/utils/orderCollectionIdentity.js +5 -0
- package/lib/modules/Order/utils.d.ts +2 -1
- package/lib/modules/Order/utils.js +49 -11
- package/lib/modules/Payment/index.js +3 -4
- package/lib/modules/Product/types.d.ts +11 -0
- package/lib/modules/ProductList/index.js +1 -1
- package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
- package/lib/modules/ResourcePlanner/planner.js +252 -8
- package/lib/modules/ResourcePlanner/types.d.ts +29 -0
- package/lib/modules/Rules/index.js +2 -1
- package/lib/modules/Schedule/index.d.ts +8 -0
- package/lib/modules/Schedule/index.js +68 -12
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +11 -0
- package/lib/plugins/request.d.ts +7 -0
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +166 -39
- package/lib/server/modules/form/index.d.ts +19 -0
- package/lib/server/modules/form/index.js +73 -0
- package/lib/server/modules/form/types.d.ts +13 -0
- package/lib/server/modules/form/types.js +9 -0
- package/lib/server/modules/index.d.ts +3 -0
- package/lib/server/modules/index.js +15 -1
- package/lib/server/modules/order/index.d.ts +19 -0
- package/lib/server/modules/order/index.js +160 -7
- package/lib/server/modules/order/types.d.ts +4 -0
- package/lib/server/modules/products/index.d.ts +28 -7
- package/lib/server/modules/products/index.js +226 -63
- package/lib/server/modules/products/replication.d.ts +8 -0
- package/lib/server/modules/products/replication.js +30 -0
- package/lib/server/modules/products/types.d.ts +12 -1
- package/lib/server/modules/products/types.js +3 -0
- package/lib/server/test.json +1 -1
- package/lib/server/utils/small-ticket.d.ts +1 -85
- package/lib/server/utils/small-ticket.js +9 -2305
- package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
- package/lib/shared/payment/loadPaymentMethods.js +40 -0
- package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
- package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
- package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
- package/lib/shared/receipt/small-ticket.d.ts +96 -0
- package/lib/shared/receipt/small-ticket.js +2555 -0
- package/lib/shared/receipt/templateVisibility.d.ts +26 -0
- package/lib/shared/receipt/templateVisibility.js +67 -0
- package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
- package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
- package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
- package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
- package/lib/solution/BaseSales/index.d.ts +43 -16
- package/lib/solution/BaseSales/index.js +401 -33
- package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
- package/lib/solution/BaseSales/pickupTiming.js +290 -0
- package/lib/solution/BaseSales/types.d.ts +12 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +7 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -8
- package/lib/solution/BookingByStep/index.d.ts +4 -2
- package/lib/solution/BookingByStep/index.js +7 -3
- package/lib/solution/BookingTicket/index.d.ts +23 -3
- package/lib/solution/BookingTicket/index.js +197 -9
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
- package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
- package/lib/solution/BookingTicket/utils/cartView.js +3 -1
- package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
- package/lib/solution/OrderInvoicePreview/index.js +246 -0
- package/lib/solution/RegisterAndLogin/config.js +57 -11
- package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
- package/lib/solution/RegisterAndLogin/index.js +9 -1
- package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
- package/lib/solution/RegisterAndLogin/utils.js +24 -17
- package/lib/solution/ScanOrder/index.js +59 -20
- package/lib/solution/ScanOrder/types.d.ts +3 -0
- package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
- package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
- package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
- package/lib/solution/UnifiedBookingSales/index.js +562 -75
- package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
- package/lib/solution/VenueBooking/index.d.ts +15 -2
- package/lib/solution/VenueBooking/index.js +243 -96
- package/lib/solution/VenueBooking/types.d.ts +2 -1
- package/lib/solution/VenueBooking/types.js +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
- package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
- package/lib/solution/index.d.ts +1 -0
- package/lib/solution/index.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { OrderModule } from '../../modules/Order';
|
|
2
|
+
import type { ShopServiceType } from '../../modules/Order/types';
|
|
3
|
+
import type { ScheduleModule } from '../../modules/Schedule';
|
|
4
|
+
import { type PickupTimingAvailability, type PickupTimingSelection, type PickupTimingValidationResult } from '../../modules/FulfillmentTiming';
|
|
5
|
+
interface PickupTimingHost {
|
|
6
|
+
getOrder: () => OrderModule;
|
|
7
|
+
setServiceType?: (serviceType: ShopServiceType) => unknown | Promise<unknown>;
|
|
8
|
+
getSchedule: () => ScheduleModule | undefined;
|
|
9
|
+
loadOpenData: (force: boolean) => Promise<Record<string, unknown>>;
|
|
10
|
+
getTimezone: () => string;
|
|
11
|
+
getScope: () => string;
|
|
12
|
+
isPos: () => boolean;
|
|
13
|
+
now?: () => Date;
|
|
14
|
+
}
|
|
15
|
+
/** Reuses runtime configuration and schedules; every calculation still uses the live clock. */
|
|
16
|
+
export declare class PickupTimingController {
|
|
17
|
+
private readonly host;
|
|
18
|
+
private latest?;
|
|
19
|
+
private runtime?;
|
|
20
|
+
private writeSequence;
|
|
21
|
+
constructor(host: PickupTimingHost);
|
|
22
|
+
private now;
|
|
23
|
+
/** A new solution context or an explicit settings refresh invalidates pending work too. */
|
|
24
|
+
invalidate(): void;
|
|
25
|
+
private assertCurrentRuntime;
|
|
26
|
+
private getRuntime;
|
|
27
|
+
private loadConfig;
|
|
28
|
+
private loadSchedules;
|
|
29
|
+
/** Preserve an existing POS choice without adding it to the shared settings cache. */
|
|
30
|
+
private getEffectiveConfig;
|
|
31
|
+
private snapshot;
|
|
32
|
+
getAvailability(params?: {
|
|
33
|
+
date?: string;
|
|
34
|
+
force?: boolean;
|
|
35
|
+
}): Promise<PickupTimingAvailability>;
|
|
36
|
+
getSelection(): PickupTimingSelection;
|
|
37
|
+
private validateSnapshot;
|
|
38
|
+
validate(selection: PickupTimingSelection): Promise<PickupTimingValidationResult>;
|
|
39
|
+
setSelection(selection: PickupTimingSelection, options?: {
|
|
40
|
+
frozen?: boolean;
|
|
41
|
+
}): Promise<PickupTimingSelection>;
|
|
42
|
+
/** Called before a new checkout/payment; payment callbacks keep their already prepared appointment. */
|
|
43
|
+
prepare(options?: {
|
|
44
|
+
freeze?: boolean;
|
|
45
|
+
}): Promise<PickupTimingSelection>;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PickupTimingController = void 0;
|
|
7
|
+
var _lodashEs = require("lodash-es");
|
|
8
|
+
var _FulfillmentTiming = require("../../modules/FulfillmentTiming");
|
|
9
|
+
async function withTimeout(request) {
|
|
10
|
+
let timer;
|
|
11
|
+
try {
|
|
12
|
+
return await Promise.race([request, new Promise((_, reject) => {
|
|
13
|
+
timer = setTimeout(() => reject(new Error('Unable to load pickup times. Please try again.')), 30000);
|
|
14
|
+
})]);
|
|
15
|
+
} finally {
|
|
16
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Reuses runtime configuration and schedules; every calculation still uses the live clock. */
|
|
21
|
+
class PickupTimingController {
|
|
22
|
+
latest;
|
|
23
|
+
runtime;
|
|
24
|
+
writeSequence = 0;
|
|
25
|
+
constructor(host) {
|
|
26
|
+
this.host = host;
|
|
27
|
+
}
|
|
28
|
+
now() {
|
|
29
|
+
return this.host.now?.() ?? new Date();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A new solution context or an explicit settings refresh invalidates pending work too. */
|
|
33
|
+
invalidate() {
|
|
34
|
+
this.runtime = undefined;
|
|
35
|
+
this.latest = undefined;
|
|
36
|
+
this.writeSequence += 1;
|
|
37
|
+
}
|
|
38
|
+
assertCurrentRuntime(runtime) {
|
|
39
|
+
if (this.runtime !== runtime || runtime.scope !== this.host.getScope()) {
|
|
40
|
+
throw new Error('Store settings changed. Please try again.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
getRuntime() {
|
|
44
|
+
const scope = this.host.getScope();
|
|
45
|
+
if (this.runtime?.scope !== scope) {
|
|
46
|
+
this.latest = undefined;
|
|
47
|
+
this.runtime = {
|
|
48
|
+
scope
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return this.runtime;
|
|
52
|
+
}
|
|
53
|
+
async loadConfig(runtime) {
|
|
54
|
+
if (runtime.config) return runtime.config;
|
|
55
|
+
if (!runtime.configRequest) {
|
|
56
|
+
const request = (async () => {
|
|
57
|
+
const config = (0, _FulfillmentTiming.normalizePickupTimingConfig)(await withTimeout(this.host.loadOpenData(false)));
|
|
58
|
+
this.assertCurrentRuntime(runtime);
|
|
59
|
+
runtime.config = config;
|
|
60
|
+
return config;
|
|
61
|
+
})();
|
|
62
|
+
runtime.configRequest = request;
|
|
63
|
+
}
|
|
64
|
+
const request = runtime.configRequest;
|
|
65
|
+
try {
|
|
66
|
+
return await request;
|
|
67
|
+
} finally {
|
|
68
|
+
if (runtime.configRequest === request) runtime.configRequest = undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async loadSchedules(runtime, config) {
|
|
72
|
+
if (runtime.schedules) return runtime.schedules;
|
|
73
|
+
if (!runtime.scheduleRequest) {
|
|
74
|
+
const request = (async () => {
|
|
75
|
+
const schedule = this.host.getSchedule();
|
|
76
|
+
if (!schedule) throw new Error('Pickup schedule is unavailable. Please try again.');
|
|
77
|
+
// Reuse the catalog loaded by solution initialization, including its in-flight request.
|
|
78
|
+
await withTimeout(schedule.loadAllSchedule({
|
|
79
|
+
useCache: true
|
|
80
|
+
}));
|
|
81
|
+
this.assertCurrentRuntime(runtime);
|
|
82
|
+
const ids = [...new Set([...config.scheduleIds, ...(config.operatingHoursScheduleIds || [])])];
|
|
83
|
+
const schedules = (0, _lodashEs.cloneDeep)(schedule.getScheduleListByIds(ids) || []);
|
|
84
|
+
runtime.schedules = schedules;
|
|
85
|
+
return schedules;
|
|
86
|
+
})();
|
|
87
|
+
runtime.scheduleRequest = request;
|
|
88
|
+
}
|
|
89
|
+
const request = runtime.scheduleRequest;
|
|
90
|
+
try {
|
|
91
|
+
return await request;
|
|
92
|
+
} finally {
|
|
93
|
+
if (runtime.scheduleRequest === request) runtime.scheduleRequest = undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Preserve an existing POS choice without adding it to the shared settings cache. */
|
|
98
|
+
getEffectiveConfig(config) {
|
|
99
|
+
if (!this.host.isPos()) return config;
|
|
100
|
+
const serviceType = this.host.getOrder().getTempOrder()?.metadata?.shop_service_data?.service_type;
|
|
101
|
+
if (serviceType !== 'dine_in' && serviceType !== 'takeaway' || config.handoverModes.includes(serviceType)) {
|
|
102
|
+
return config;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
...config,
|
|
106
|
+
handoverModes: [...config.handoverModes, serviceType]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async snapshot(includeSchedule, tolerateScheduleError = false) {
|
|
110
|
+
const runtime = this.getRuntime();
|
|
111
|
+
const config = await this.loadConfig(runtime);
|
|
112
|
+
this.assertCurrentRuntime(runtime);
|
|
113
|
+
let schedules = [];
|
|
114
|
+
let error;
|
|
115
|
+
if (includeSchedule && config.handoverModes.includes('pick_up') && config.timingMode !== 'asap_only' && config.scheduleIds.length) {
|
|
116
|
+
try {
|
|
117
|
+
schedules = await this.loadSchedules(runtime, config);
|
|
118
|
+
} catch (reason) {
|
|
119
|
+
if (!tolerateScheduleError) throw reason;
|
|
120
|
+
error = reason instanceof Error ? reason.message : 'Pickup schedule is unavailable. Please try again.';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.assertCurrentRuntime(runtime);
|
|
124
|
+
const result = {
|
|
125
|
+
config,
|
|
126
|
+
timezone: this.host.getTimezone(),
|
|
127
|
+
schedules,
|
|
128
|
+
scope: runtime.scope,
|
|
129
|
+
error
|
|
130
|
+
};
|
|
131
|
+
this.latest = result;
|
|
132
|
+
// Read the live order after async loading; cached snapshots retain only configured modes.
|
|
133
|
+
return {
|
|
134
|
+
...result,
|
|
135
|
+
config: this.getEffectiveConfig(config)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async getAvailability(params = {}) {
|
|
139
|
+
// `force` remains accepted for older callers; refresh recomputes time using the runtime catalog.
|
|
140
|
+
const snapshot = await this.snapshot(true, true);
|
|
141
|
+
const now = this.now();
|
|
142
|
+
try {
|
|
143
|
+
return {
|
|
144
|
+
...(0, _FulfillmentTiming.computePickupTimingAvailability)({
|
|
145
|
+
...snapshot,
|
|
146
|
+
date: params.date,
|
|
147
|
+
now
|
|
148
|
+
}),
|
|
149
|
+
error: snapshot.error
|
|
150
|
+
};
|
|
151
|
+
} catch (reason) {
|
|
152
|
+
// Keep the handover selector usable when only Pickup's timezone is unavailable.
|
|
153
|
+
return {
|
|
154
|
+
config: snapshot.config,
|
|
155
|
+
timezone: snapshot.timezone,
|
|
156
|
+
now: now.toISOString(),
|
|
157
|
+
today: '',
|
|
158
|
+
maxDate: '',
|
|
159
|
+
date: params.date || '',
|
|
160
|
+
dates: [],
|
|
161
|
+
slots: [],
|
|
162
|
+
error: reason instanceof Error ? reason.message : 'Pickup times are unavailable. Please try again.'
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
getSelection() {
|
|
167
|
+
const order = this.host.getOrder();
|
|
168
|
+
const tempOrder = order.getTempOrder();
|
|
169
|
+
const booking = order.getPickupTimingBooking();
|
|
170
|
+
const config = this.latest?.scope === this.host.getScope() ? this.getEffectiveConfig(this.latest.config) : undefined;
|
|
171
|
+
const storedServiceType = String(tempOrder?.metadata?.shop_service_data?.service_type || '');
|
|
172
|
+
const serviceType = config?.handoverModes.length ? config.handoverModes.includes(storedServiceType) ? storedServiceType : config.handoverModes[0] : storedServiceType;
|
|
173
|
+
const details = serviceType === 'pick_up' ? booking?.metadata.fulfillment_timing : undefined;
|
|
174
|
+
const mode = config?.timingMode === 'asap_only' ? 'asap' : config?.timingMode === 'scheduled_only' ? 'scheduled' : details?.mode ?? 'asap';
|
|
175
|
+
const sameMode = details?.mode === mode;
|
|
176
|
+
return {
|
|
177
|
+
serviceType,
|
|
178
|
+
mode,
|
|
179
|
+
source: mode === 'asap' ? 'asap' : sameMode && details?.source || 'schedule',
|
|
180
|
+
...(sameMode && booking ? {
|
|
181
|
+
date: booking.start_date,
|
|
182
|
+
time: booking.start_time,
|
|
183
|
+
instant: details?.instant
|
|
184
|
+
} : {})
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async validateSnapshot(selection) {
|
|
188
|
+
const snapshot = await this.snapshot(selection.serviceType === 'pick_up' && selection.mode === 'scheduled' && selection.source !== 'pos_manual');
|
|
189
|
+
const now = this.now();
|
|
190
|
+
const result = (0, _FulfillmentTiming.validatePickupTimingSelection)(selection, {
|
|
191
|
+
...snapshot,
|
|
192
|
+
now,
|
|
193
|
+
allowManualOverride: this.host.isPos()
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
snapshot,
|
|
197
|
+
now,
|
|
198
|
+
result
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
async validate(selection) {
|
|
202
|
+
return (await this.validateSnapshot(selection)).result;
|
|
203
|
+
}
|
|
204
|
+
async setSelection(selection, options = {}) {
|
|
205
|
+
const order = this.host.getOrder();
|
|
206
|
+
const tempOrder = order.ensureTempOrder();
|
|
207
|
+
const sequence = ++this.writeSequence;
|
|
208
|
+
const {
|
|
209
|
+
snapshot,
|
|
210
|
+
now,
|
|
211
|
+
result
|
|
212
|
+
} = await this.validateSnapshot(selection);
|
|
213
|
+
if (sequence !== this.writeSequence || order.getTempOrder() !== tempOrder || snapshot.scope !== this.host.getScope()) {
|
|
214
|
+
throw new Error('The order changed. Please choose the pickup time again.');
|
|
215
|
+
}
|
|
216
|
+
if (!result.valid) throw new Error(result.message || 'Please choose a valid pickup time.');
|
|
217
|
+
if (!snapshot.config.handoverModes.length) {
|
|
218
|
+
order.clearPickupTimingBooking();
|
|
219
|
+
return this.getSelection();
|
|
220
|
+
}
|
|
221
|
+
if (selection.serviceType !== 'pick_up') {
|
|
222
|
+
if (this.host.setServiceType) {
|
|
223
|
+
await this.host.setServiceType(selection.serviceType);
|
|
224
|
+
} else {
|
|
225
|
+
order.updateTempOrderServiceType(selection.serviceType);
|
|
226
|
+
}
|
|
227
|
+
return this.getSelection();
|
|
228
|
+
}
|
|
229
|
+
const slot = selection.mode === 'asap' ? (0, _FulfillmentTiming.getAsapPickupTiming)({
|
|
230
|
+
...snapshot,
|
|
231
|
+
now
|
|
232
|
+
}) : result.slot;
|
|
233
|
+
if (!slot) throw new Error('Please choose a pickup time.');
|
|
234
|
+
// Validate everything before either field is changed; notify once after the combined update.
|
|
235
|
+
tempOrder.metadata = {
|
|
236
|
+
...(tempOrder.metadata || {}),
|
|
237
|
+
shop_service_data: {
|
|
238
|
+
...(tempOrder.metadata?.shop_service_data || {}),
|
|
239
|
+
service_type: 'pick_up'
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
order.setPickupTimingBooking({
|
|
243
|
+
mode: selection.mode,
|
|
244
|
+
source: selection.mode === 'asap' ? 'asap' : selection.source === 'pos_manual' ? 'pos_manual' : 'schedule',
|
|
245
|
+
date: slot.date,
|
|
246
|
+
time: slot.time,
|
|
247
|
+
instant: slot.instant,
|
|
248
|
+
timezone: snapshot.timezone,
|
|
249
|
+
frozen: options.frozen ?? false
|
|
250
|
+
});
|
|
251
|
+
return this.getSelection();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Called before a new checkout/payment; payment callbacks keep their already prepared appointment. */
|
|
255
|
+
async prepare(options = {}) {
|
|
256
|
+
const order = this.host.getOrder();
|
|
257
|
+
const tempOrder = order.getTempOrder();
|
|
258
|
+
const sequence = this.writeSequence;
|
|
259
|
+
if (order.getOrderIdentity()?.isSubmitted) return this.getSelection();
|
|
260
|
+
const booking = order.getPickupTimingBooking();
|
|
261
|
+
if (booking?.metadata.fulfillment_timing?.frozen) return this.getSelection();
|
|
262
|
+
// An actual payment callback must never revalidate or move the time after funds have been taken.
|
|
263
|
+
const paymentStatus = order.getTempOrder()?.payment_status;
|
|
264
|
+
if (paymentStatus === 'paid' || paymentStatus === 'partially_paid') {
|
|
265
|
+
if (booking?.metadata.fulfillment_timing) {
|
|
266
|
+
const detail = booking.metadata.fulfillment_timing;
|
|
267
|
+
order.setPickupTimingBooking({
|
|
268
|
+
...detail,
|
|
269
|
+
date: booking.start_date,
|
|
270
|
+
time: booking.start_time,
|
|
271
|
+
frozen: true
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return this.getSelection();
|
|
275
|
+
}
|
|
276
|
+
const snapshot = await this.snapshot(false);
|
|
277
|
+
if (order !== this.host.getOrder() || order.getTempOrder() !== tempOrder || sequence !== this.writeSequence) {
|
|
278
|
+
throw new Error('The order changed. Please choose the pickup time again.');
|
|
279
|
+
}
|
|
280
|
+
const selection = this.getSelection();
|
|
281
|
+
if (!snapshot.config.handoverModes.length) {
|
|
282
|
+
order.clearPickupTimingBooking();
|
|
283
|
+
return selection;
|
|
284
|
+
}
|
|
285
|
+
return this.setSelection(selection, {
|
|
286
|
+
frozen: options.freeze ?? false
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
exports.PickupTimingController = PickupTimingController;
|
|
@@ -4,6 +4,8 @@ import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderCon
|
|
|
4
4
|
import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
|
|
5
5
|
import type { QuotationCustomerScopeInfo } from '../../modules/Quotation/types';
|
|
6
6
|
import type { PaymentMethod } from '../../modules/Payment/types';
|
|
7
|
+
import type { OrderHolderRelation, OrderPaymentSource } from '../../modules/Order/types';
|
|
8
|
+
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
7
9
|
/**
|
|
8
10
|
* BaseSales 流程 hook 后缀。
|
|
9
11
|
* 完整事件名应由当前模块名动态拼接,避免多个实例共享固定事件 key。
|
|
@@ -27,6 +29,15 @@ export interface BaseSalesCashPaymentOptions {
|
|
|
27
29
|
/** 指定现金支付方式;省略时使用默认 CASHMANUAL。 */
|
|
28
30
|
paymentMethodId?: number | string;
|
|
29
31
|
}
|
|
32
|
+
export interface BaseSalesSubmitSalesOrderParams {
|
|
33
|
+
payments?: OrderPaymentSource[];
|
|
34
|
+
paymentStatus?: BaseSalesPaymentStatus;
|
|
35
|
+
smallTicketDataFlag?: number;
|
|
36
|
+
confirmPendingVoucherPayments?: boolean;
|
|
37
|
+
enhancePayload?: SubmitPayloadEnhancer;
|
|
38
|
+
/** Create the order without executing payment; payment status comes from the server. */
|
|
39
|
+
paymentExecution?: 'deferred';
|
|
40
|
+
}
|
|
30
41
|
export interface BaseSalesCashPaymentConfig {
|
|
31
42
|
available: boolean;
|
|
32
43
|
paymentMethod?: PaymentMethod;
|
|
@@ -266,6 +277,7 @@ export interface BaseSalesTempOrder {
|
|
|
266
277
|
contacts: any[];
|
|
267
278
|
contacts_info: Record<string, any> | null;
|
|
268
279
|
holder: Record<string, any> | null;
|
|
280
|
+
holder_relations?: OrderHolderRelation[];
|
|
269
281
|
metadata: Record<string, any>;
|
|
270
282
|
_extend?: {
|
|
271
283
|
productsByUid?: Record<string, Record<string, any>>;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - 不在此处发明等价关系;UI 侧(ticketBooking)若需要别的字段,由 view-model 适配层做转换
|
|
15
15
|
*/
|
|
16
16
|
import type { BaseSalesOrderProduct } from '../types';
|
|
17
|
-
import type { OrderMetaList } from '../../../modules/Order/types';
|
|
17
|
+
import type { OrderHolderRelation, OrderMetaList } from '../../../modules/Order/types';
|
|
18
18
|
export interface ISalesDetailHeader {
|
|
19
19
|
order_id: number | string | null;
|
|
20
20
|
order_number?: string;
|
|
@@ -121,6 +121,8 @@ export interface ISalesDetail {
|
|
|
121
121
|
header: ISalesDetailHeader;
|
|
122
122
|
/** 商品行快照(保留 tempOrder / 后端详情原字段) */
|
|
123
123
|
products: BaseSalesOrderProduct[];
|
|
124
|
+
/** 非预约商品 Holder 关系,保留关系及 metadata 的扩展字段。 */
|
|
125
|
+
holder_relations?: OrderHolderRelation[];
|
|
124
126
|
/** 全部 bookings,按服务端原始顺序输出(含 root + child) */
|
|
125
127
|
bookings: ISalesBooking[];
|
|
126
128
|
/** root booking(parent_id === 0),多个时取首个,无则为 null */
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.parseSalesResponse = parseSalesResponse;
|
|
7
7
|
var _orderCollectionIdentity = require("../../../modules/Order/utils/orderCollectionIdentity");
|
|
8
|
+
var _pickupTiming = require("../../../modules/Order/pickupTiming");
|
|
9
|
+
var _lodashEs = require("lodash-es");
|
|
8
10
|
/**
|
|
9
11
|
* 把 `/order/sales/{id}` 响应(OrderData)解析为 ISalesDetail。
|
|
10
12
|
*
|
|
@@ -64,6 +66,7 @@ function pickCustomer(raw) {
|
|
|
64
66
|
*/
|
|
65
67
|
function isRootBooking(booking) {
|
|
66
68
|
if (!booking || typeof booking !== 'object') return false;
|
|
69
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) return false;
|
|
67
70
|
const parentId = booking.parent_id;
|
|
68
71
|
if (parentId === 0 || parentId === null || parentId === undefined) return true;
|
|
69
72
|
return false;
|
|
@@ -71,6 +74,7 @@ function isRootBooking(booking) {
|
|
|
71
74
|
function indexBookingsByProductUid(bookings) {
|
|
72
75
|
const result = {};
|
|
73
76
|
for (const b of bookings) {
|
|
77
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(b)) continue;
|
|
74
78
|
const uid = b && (b.product_uid || b.metadata?.product_uid) || '';
|
|
75
79
|
if (!uid) continue;
|
|
76
80
|
const key = String(uid);
|
|
@@ -127,6 +131,9 @@ function parseSalesResponse(input) {
|
|
|
127
131
|
return {
|
|
128
132
|
header: pickHeader(raw),
|
|
129
133
|
products,
|
|
134
|
+
...(Array.isArray(raw?.holder_relations) ? {
|
|
135
|
+
holder_relations: (0, _lodashEs.cloneDeep)(raw.holder_relations)
|
|
136
|
+
} : {}),
|
|
130
137
|
bookings,
|
|
131
138
|
rootBooking,
|
|
132
139
|
bookingsByProductUid,
|
|
@@ -5,7 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.transformBaseProductToOrderProduct = transformBaseProductToOrderProduct;
|
|
7
7
|
var _weighedProduct = require("../../../modules/Order/utils/weighedProduct");
|
|
8
|
-
var _utils = require("../../../modules/
|
|
8
|
+
var _utils = require("../../../modules/Holder/utils");
|
|
9
|
+
var _serviceTimes = require("../../../modules/BookingContext/utils/serviceTimes");
|
|
10
|
+
var _utils2 = require("../../../modules/Order/utils");
|
|
9
11
|
var _manualProductDiscount = require("../../../modules/Order/utils/manualProductDiscount");
|
|
10
12
|
function toNumber(value, fallback = 0) {
|
|
11
13
|
const parsedValue = Number(value);
|
|
@@ -108,7 +110,7 @@ function normalizeBundleItems(bundleItems, preferPriceField = false, preferBundl
|
|
|
108
110
|
discount_list: preferPriceField ? [] : bundleItem.discount_list
|
|
109
111
|
};
|
|
110
112
|
// bundle_selling_price 落「正净额」:markdown = |price| − Σoptions;markup/原价维持原值。
|
|
111
|
-
normalizedItem.bundle_selling_price = (0,
|
|
113
|
+
normalizedItem.bundle_selling_price = (0, _utils2.getBundleSellingMagnitude)(magnitudeSource).toFixed(2);
|
|
112
114
|
if ((normalizedItem.price_type ?? normalizedItem.custom_price_type) === 'markdown' && (normalizedItem.price_type_ext === '' || normalizedItem.price_type_ext === undefined || normalizedItem.price_type_ext === null)) {
|
|
113
115
|
normalizedItem.custom_price = normalizedItem.custom_price ?? normalizedItem.price;
|
|
114
116
|
normalizedItem.price = normalizedItem.bundle_selling_price;
|
|
@@ -158,14 +160,14 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
158
160
|
const explicitLineTotal = payload.line_total ?? payload.total ?? payload._extend?.total;
|
|
159
161
|
const hasExplicitLineTotal = Number.isFinite(Number(explicitLineTotal));
|
|
160
162
|
const lineCompositeTotal = toPriceString(explicitLineTotal, sourceProductPrice);
|
|
161
|
-
const productOptionItem = (0,
|
|
163
|
+
const productOptionItem = (0, _utils2.normalizeProductSkuOptions)(normalizeOptionItems(payload.product_sku?.option ?? payload.option ?? payload.options ?? payload.product_option_item, hasPriceOverride || weighedSourcePrice !== undefined));
|
|
162
164
|
const productBundle = normalizeBundleItems(payload.bundle ?? payload.product_bundle, hasPriceOverride, hasPriceOverride && weighedSourcePrice !== undefined);
|
|
163
165
|
// `payload.unique` 是业务侧商品/票务标识,可能在连续加同一商品时重复;
|
|
164
166
|
// 行级唯一值只接受显式协议字段,缺省交给 OrderModule 生成。
|
|
165
167
|
const uniqueIdentificationNumber = payload.unique_identification_number;
|
|
166
168
|
const resolvedQuantity = toSafePositiveInt(payload.quantity ?? payload.num, 1);
|
|
167
|
-
const originTotal = weighedSourcePrice !== undefined ? Number((0,
|
|
168
|
-
mainPrice: Number(weighedSourcePrice) + (0,
|
|
169
|
+
const originTotal = weighedSourcePrice !== undefined ? Number((0, _utils2.composeLinePrice)({
|
|
170
|
+
mainPrice: Number(weighedSourcePrice) + (0, _utils2.sumOptionUnitPrice)(productOptionItem).toNumber(),
|
|
169
171
|
bundle: hasPriceOverride ? (0, _weighedProduct.withOriginalBundleOptionPrices)(productBundle) : productBundle,
|
|
170
172
|
useOriginalBundle: true
|
|
171
173
|
})) : (0, _manualProductDiscount.resolveManualDiscountOriginTotal)({
|
|
@@ -197,14 +199,15 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
197
199
|
})) : payload.discount_list || [];
|
|
198
200
|
|
|
199
201
|
// v2:source 不含 option;main_product_* 含 option(与 normalizeOrderProduct 一致)
|
|
200
|
-
const optionSum = (0,
|
|
202
|
+
const optionSum = (0, _utils2.sumOptionUnitPrice)(productOptionItem).toNumber();
|
|
201
203
|
const mainProductOriginalPrice = toPriceString(Number(sourceProductPrice) + optionSum);
|
|
202
|
-
const bundleOnlyComposite = (0,
|
|
204
|
+
const bundleOnlyComposite = (0, _utils2.composeLinePrice)({
|
|
203
205
|
mainPrice: 0,
|
|
204
206
|
bundle: productBundle
|
|
205
207
|
});
|
|
206
208
|
const derivedMainSelling = hasExplicitLineTotal ? Number(lineCompositeTotal) - Number(bundleOnlyComposite) : Number(mainProductOriginalPrice);
|
|
207
209
|
const mainProductSellingPrice = toPriceString(Number.isFinite(derivedMainSelling) && derivedMainSelling >= 0 ? derivedMainSelling : Number(mainProductOriginalPrice));
|
|
210
|
+
const holderRelations = [payload._extend, callbackOrigin?._extend, sourceProduct?._extend].find(source => Array.isArray(source?.holder_relations))?.holder_relations;
|
|
208
211
|
const metadata = {
|
|
209
212
|
unique: payload.unique,
|
|
210
213
|
session: payload.session,
|
|
@@ -219,7 +222,7 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
219
222
|
main_product_selling_price: mainProductSellingPrice,
|
|
220
223
|
main_product_original_price: mainProductOriginalPrice,
|
|
221
224
|
price_schema_version: 2,
|
|
222
|
-
holder_config: sourceProduct
|
|
225
|
+
holder_config: (0, _utils.resolveProductHolderConfig)(sourceProduct) ?? undefined,
|
|
223
226
|
...(dataVariantIds !== undefined ? {
|
|
224
227
|
data_variant_ids: dataVariantIds
|
|
225
228
|
} : {}),
|
|
@@ -264,6 +267,11 @@ function transformBaseProductToOrderProduct(params) {
|
|
|
264
267
|
tax_fee: toPriceString(payload.tax_fee ?? matchedVariant?.tax_fee ?? origin?.tax_fee ?? sourceProduct?.tax_fee, '0.00'),
|
|
265
268
|
is_charge_tax: toNumber(payload.is_charge_tax ?? matchedVariant?.is_charge_tax ?? origin?.is_charge_tax ?? sourceProduct?.is_charge_tax, 0),
|
|
266
269
|
metadata,
|
|
270
|
+
...(holderRelations !== undefined && !(0, _serviceTimes.isBookingProduct)(origin) && !(0, _serviceTimes.isBookingProduct)(payload) ? {
|
|
271
|
+
_extend: {
|
|
272
|
+
holder_relations: holderRelations
|
|
273
|
+
}
|
|
274
|
+
} : {}),
|
|
267
275
|
note: payload.note != null ? String(payload.note) : '',
|
|
268
276
|
product_title: productTitle,
|
|
269
277
|
product_cover: firstNonBlank(matchedVariant?.cover, sourceProduct?.cover),
|
|
@@ -210,6 +210,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
210
210
|
* product: ProductData;
|
|
211
211
|
* date?: { startTime: string; endTime: string } | null;
|
|
212
212
|
* account?: Account | null;
|
|
213
|
+
* isLegacyOrder?: boolean;
|
|
213
214
|
* })} {
|
|
214
215
|
* product,
|
|
215
216
|
* date,
|
|
@@ -218,13 +219,14 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
218
219
|
* @return {*}
|
|
219
220
|
* @memberof BookingByStepImpl
|
|
220
221
|
*/
|
|
221
|
-
addProductToCart({ product, date, account, }: {
|
|
222
|
+
addProductToCart({ product, date, account, isLegacyOrder, }: {
|
|
222
223
|
product: ProductData;
|
|
223
224
|
date?: {
|
|
224
225
|
startTime: string;
|
|
225
226
|
endTime: string;
|
|
226
227
|
} | null;
|
|
227
228
|
account?: Account | null;
|
|
229
|
+
isLegacyOrder?: boolean;
|
|
228
230
|
}): {
|
|
229
231
|
success: boolean;
|
|
230
232
|
errorCode?: string;
|
|
@@ -326,7 +328,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
328
|
date: string;
|
|
327
329
|
status: string;
|
|
328
330
|
week: string;
|
|
329
|
-
weekNum: 0 | 5 |
|
|
331
|
+
weekNum: 0 | 5 | 1 | 2 | 4 | 3 | 6;
|
|
330
332
|
}[]>;
|
|
331
333
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
334
|
private getScheduleDataByIds;
|
|
@@ -636,7 +636,8 @@ class BookingByStepImpl extends _BaseModule.BaseModule {
|
|
|
636
636
|
// 直接调用 addProductToCart,不传递 date 参数以避免日期检查逻辑
|
|
637
637
|
return this.addProductToCart({
|
|
638
638
|
product: productData,
|
|
639
|
-
account: activeAccount
|
|
639
|
+
account: activeAccount,
|
|
640
|
+
isLegacyOrder: true
|
|
640
641
|
});
|
|
641
642
|
}
|
|
642
643
|
|
|
@@ -647,6 +648,7 @@ class BookingByStepImpl extends _BaseModule.BaseModule {
|
|
|
647
648
|
* product: ProductData;
|
|
648
649
|
* date?: { startTime: string; endTime: string } | null;
|
|
649
650
|
* account?: Account | null;
|
|
651
|
+
* isLegacyOrder?: boolean;
|
|
650
652
|
* })} {
|
|
651
653
|
* product,
|
|
652
654
|
* date,
|
|
@@ -658,7 +660,8 @@ class BookingByStepImpl extends _BaseModule.BaseModule {
|
|
|
658
660
|
addProductToCart({
|
|
659
661
|
product,
|
|
660
662
|
date,
|
|
661
|
-
account
|
|
663
|
+
account,
|
|
664
|
+
isLegacyOrder = false
|
|
662
665
|
}) {
|
|
663
666
|
const {
|
|
664
667
|
bundle,
|
|
@@ -725,7 +728,8 @@ class BookingByStepImpl extends _BaseModule.BaseModule {
|
|
|
725
728
|
product: productData,
|
|
726
729
|
bundle,
|
|
727
730
|
options,
|
|
728
|
-
quantity
|
|
731
|
+
quantity,
|
|
732
|
+
isLegacyOrder
|
|
729
733
|
};
|
|
730
734
|
if (date) {
|
|
731
735
|
addItemParams.date = date;
|
|
@@ -32,6 +32,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
32
32
|
private orderCustomerDiscountRefreshCustomerId;
|
|
33
33
|
private orderCustomerDiscountRefreshTarget;
|
|
34
34
|
private orderCustomerPromotionRefreshInFlight;
|
|
35
|
+
private orderCustomerContactRequest;
|
|
35
36
|
private readonly customerResolveRequests;
|
|
36
37
|
protected loadOpenDataInFlight: Promise<OpenDataConfig> | null;
|
|
37
38
|
protected loadOpenDataInFlightTarget: string | null;
|
|
@@ -42,6 +43,10 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
42
43
|
*/
|
|
43
44
|
protected getRegisteredModuleNames(): readonly string[];
|
|
44
45
|
protected getSubmitOrderSalesChannel(): string;
|
|
46
|
+
/** 供销售展示层按 booking.resources[].form_id 读取当前多语言表单标题。 */
|
|
47
|
+
getFormTitleMap(): Record<string, Record<string, string> | string>;
|
|
48
|
+
/** 表单定义由 Ably 更新后通知展示层刷新,不改动订单里的历史 metadata。 */
|
|
49
|
+
onFormTitlesChanged(callback: (titles: Record<string, Record<string, string> | string>) => void): () => void;
|
|
45
50
|
/**
|
|
46
51
|
* 业务侧子模块工厂:BookingTicket 自带的 createBookingTicketModule 优先匹配;
|
|
47
52
|
* 未识别的模块名(如 BookingByStep 公共类型)回退到父类工厂。
|
|
@@ -53,11 +58,13 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
53
58
|
* 在解决方案对外 ready 前准备 Invoice Document;失败只降级模板,不阻断销售。
|
|
54
59
|
* 已由页面取得的 OpenData 直接交给模块接管,没有注入数据时再走 target-scoped 加载。
|
|
55
60
|
*/
|
|
56
|
-
|
|
61
|
+
protected prepareInvoiceTemplateAtSolutionReady(injectedOpenData?: OpenDataConfig): Promise<void>;
|
|
57
62
|
protected getBookingTicketBusinessCode(): string | null;
|
|
58
63
|
private getIdGeneratorPlugin;
|
|
59
|
-
|
|
64
|
+
protected loadOpenDataConfig(): Promise<OpenDataConfig | null>;
|
|
60
65
|
getOpenData(): Promise<OpenDataConfig | null>;
|
|
66
|
+
protected loadContactInfoOpenData(): Promise<OpenDataConfig | null>;
|
|
67
|
+
protected loadFulfillmentItemRuleOpenData(): Promise<OpenDataConfig | null>;
|
|
61
68
|
getInvoiceLayoutConfig(): Promise<InvoiceLayoutConfig>;
|
|
62
69
|
getInvoiceTemplateSettings(): Promise<InvoiceTemplateSettings>;
|
|
63
70
|
protected isInvoiceOpenDataCacheCurrent(): boolean;
|
|
@@ -66,6 +73,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
66
73
|
private getShortNumberOrDeviceId;
|
|
67
74
|
private configureIdGeneratorFromOpenData;
|
|
68
75
|
private normalizePositiveInteger;
|
|
76
|
+
private normalizeShortNumberMaximum;
|
|
69
77
|
private normalizeIdPrefix;
|
|
70
78
|
/**
|
|
71
79
|
* 加载销售详情,并在父类基础上把 customer 信息装配到 CustomerModule。
|
|
@@ -275,6 +283,16 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
275
283
|
setOrderCustomer(customer: ICustomer | null, options?: {
|
|
276
284
|
source?: OrderCustomerChangePayload['source'];
|
|
277
285
|
}): void;
|
|
286
|
+
private resetOrderCustomerContactInfo;
|
|
287
|
+
/** Explicit edits, including clearing the contact, must win over a pending default. */
|
|
288
|
+
updateTempOrderContactsInfo(contact: Record<string, any> | null): Record<string, any> | null;
|
|
289
|
+
private getCustomerContactScope;
|
|
290
|
+
private getCustomerContactOrderKey;
|
|
291
|
+
replaceTempOrder(...args: Parameters<BaseSalesImpl['replaceTempOrder']>): Promise<import("../../modules/Order/types").OrderTempOrder>;
|
|
292
|
+
private applyDefaultOrderCustomerContactInfo;
|
|
293
|
+
private prefillOrderCustomerContactInfo;
|
|
294
|
+
protected waitForOrderCustomerContactInfo(): Promise<void>;
|
|
295
|
+
validateContactInfo(): Promise<void>;
|
|
278
296
|
/**
|
|
279
297
|
* 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
|
|
280
298
|
*/
|
|
@@ -286,7 +304,9 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
286
304
|
/**
|
|
287
305
|
* 清空下单客户(协议字段 + snapshot)。
|
|
288
306
|
*/
|
|
289
|
-
clearOrderCustomer(
|
|
307
|
+
clearOrderCustomer(options?: {
|
|
308
|
+
preserveContactInfo?: boolean;
|
|
309
|
+
}): void;
|
|
290
310
|
/**
|
|
291
311
|
* 重置 tempOrder,并同步清空下单客户运行态。
|
|
292
312
|
*
|