@pisell/pisellos 0.10.43 → 0.10.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
- package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/dist/model/strategy/adapter/itemRule/type.js +19 -1
- package/dist/modules/Order/index.d.ts +41 -9
- package/dist/modules/Order/index.js +1438 -878
- package/dist/modules/Order/salesNotes.d.ts +31 -0
- package/dist/modules/Order/salesNotes.js +492 -0
- package/dist/modules/Order/types.d.ts +105 -8
- package/dist/modules/Order/types.js +6 -1
- package/dist/modules/Order/utils.d.ts +3 -1
- package/dist/modules/Order/utils.js +191 -71
- package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
- package/dist/modules/Payment/cashRecommendationAlgorithm.js +17 -367
- package/dist/modules/ProductList/index.d.ts +2 -1
- package/dist/modules/ProductList/index.js +100 -20
- package/dist/modules/ProductList/types.d.ts +10 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +45 -3
- package/dist/server/modules/order/index.js +6 -0
- package/dist/server/modules/order/types.d.ts +9 -0
- package/dist/server/utils/small-ticket.d.ts +1 -0
- package/dist/server/utils/small-ticket.js +142 -14
- package/dist/solution/BaseSales/index.d.ts +15 -1
- package/dist/solution/BaseSales/index.js +1240 -877
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -0
- package/dist/solution/BookingTicket/index.js +37 -16
- package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
- package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
- package/dist/solution/RegisterAndLogin/config.js +95 -40
- package/dist/solution/RegisterAndLogin/index.js +4 -1
- package/dist/solution/ScanOrder/index.d.ts +1 -0
- package/dist/solution/ScanOrder/index.js +31 -27
- package/dist/solution/ScanOrder/utils.d.ts +1 -0
- package/dist/solution/ScanOrder/utils.js +2 -0
- package/dist/solution/UnifiedBookingSales/index.d.ts +15 -2
- package/dist/solution/UnifiedBookingSales/index.js +777 -510
- package/dist/solution/UnifiedBookingSales/types.d.ts +14 -1
- package/dist/solution/VenueBooking/index.d.ts +1 -0
- package/dist/solution/VenueBooking/index.js +8 -4
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
- package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
- package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
- package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
- package/lib/model/strategy/adapter/itemRule/type.js +19 -1
- package/lib/modules/Order/index.d.ts +41 -9
- package/lib/modules/Order/index.js +434 -61
- package/lib/modules/Order/salesNotes.d.ts +31 -0
- package/lib/modules/Order/salesNotes.js +382 -0
- package/lib/modules/Order/types.d.ts +105 -8
- package/lib/modules/Order/types.js +5 -1
- package/lib/modules/Order/utils.d.ts +3 -1
- package/lib/modules/Order/utils.js +114 -1
- package/lib/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +9 -354
- package/lib/modules/ProductList/index.d.ts +2 -1
- package/lib/modules/ProductList/index.js +47 -2
- package/lib/modules/ProductList/types.d.ts +10 -0
- package/lib/server/index.d.ts +7 -0
- package/lib/server/index.js +39 -3
- package/lib/server/modules/order/index.js +6 -0
- package/lib/server/modules/order/types.d.ts +9 -0
- package/lib/server/utils/small-ticket.d.ts +1 -0
- package/lib/server/utils/small-ticket.js +136 -12
- package/lib/solution/BaseSales/index.d.ts +15 -1
- package/lib/solution/BaseSales/index.js +192 -22
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -0
- package/lib/solution/BookingTicket/index.js +23 -5
- package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
- package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
- package/lib/solution/RegisterAndLogin/config.js +49 -8
- package/lib/solution/RegisterAndLogin/index.js +4 -1
- package/lib/solution/ScanOrder/index.d.ts +1 -0
- package/lib/solution/ScanOrder/index.js +5 -1
- package/lib/solution/ScanOrder/utils.d.ts +1 -0
- package/lib/solution/ScanOrder/utils.js +1 -0
- package/lib/solution/UnifiedBookingSales/index.d.ts +15 -2
- package/lib/solution/UnifiedBookingSales/index.js +125 -1
- package/lib/solution/UnifiedBookingSales/types.d.ts +14 -1
- package/lib/solution/VenueBooking/index.d.ts +1 -0
- package/lib/solution/VenueBooking/index.js +5 -1
- package/package.json +1 -1
|
@@ -1200,7 +1200,11 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1200
1200
|
return sourceMap;
|
|
1201
1201
|
}
|
|
1202
1202
|
getItemRuleRuntimeConfig() {
|
|
1203
|
-
|
|
1203
|
+
const runtimeConfig = this.itemRuleRuntimeConfig || {};
|
|
1204
|
+
return {
|
|
1205
|
+
...runtimeConfig,
|
|
1206
|
+
channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel ?? this.otherParams?.channel
|
|
1207
|
+
};
|
|
1204
1208
|
}
|
|
1205
1209
|
async ensureItemRuleConfigsLoaded() {
|
|
1206
1210
|
if (this.itemRuleConfigs.length > 0) return this.itemRuleConfigs;
|
|
@@ -333,6 +333,7 @@ function buildItemRuleBusinessData(params) {
|
|
|
333
333
|
cartItems,
|
|
334
334
|
historicalItems,
|
|
335
335
|
serviceType: runtimeConfig.serviceType || 'dine-in',
|
|
336
|
+
channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel,
|
|
336
337
|
submissionIndex: typeof runtimeConfig.submissionIndex === 'number' ? toNonNegativeInt(runtimeConfig.submissionIndex) : tempOrder.order_id ? 1 : 0,
|
|
337
338
|
custom: runtimeConfig.custom || {},
|
|
338
339
|
strategyConfigs: itemRuleConfigs
|
|
@@ -2,10 +2,11 @@ import type { Module, ModuleOptions, PisellCore } from '../../types';
|
|
|
2
2
|
import type { ProductData } from '../../modules';
|
|
3
3
|
import { type InvoiceLayoutConfig, type InvoiceTemplateSettings, type OpenDataConfig } from '../../modules/OpenData';
|
|
4
4
|
import type { LoadScheduleAvailableDateParams, ScheduleItem } from '../../modules/Schedule/types';
|
|
5
|
-
import type { ProductListLoadProductsParams } from '../../modules/ProductList';
|
|
5
|
+
import type { ProductListLoadProductsParams, ProductListStoreQueryParams } from '../../modules/ProductList';
|
|
6
6
|
import type { AvailabilityDateRange, AvailabilityOccupancy, AvailabilityProduct, AvailabilityResource, GetProductTimeRangesRequest } from '../../modules/ResourcePlanner';
|
|
7
|
-
import type { AvailabilityContextRef, ContextualAvailabilityQuery, ContextualAvailabilityQueryResult, ContextualCommitAvailabilitySelectionParams, ContextualProductTimeRangeGroup, UnifiedBookingSalesAddRetailProductParams, UnifiedBookingSalesApplyPlannerDiscountsParams, UnifiedBookingSalesCommitAvailabilitySelectionResult, UnifiedBookingSalesDiscountResult, UnifiedBookingSalesLoadProductsByScheduleDateParams, UnifiedBookingSalesLoadOpenDataParams, UnifiedBookingSalesPrepareAvailabilityProjectionParams, UnifiedBookingSalesPolicyResponse, UnifiedBookingSalesStageRetailProductsParams, UnifiedBookingSalesState } from './types';
|
|
7
|
+
import type { AvailabilityContextRef, ContextualAvailabilityQuery, ContextualAvailabilityQueryResult, ContextualCommitAvailabilitySelectionParams, ContextualProductTimeRangeGroup, UnifiedBookingSalesAddRetailProductParams, UnifiedBookingSalesApplyPlannerDiscountsParams, UnifiedBookingSalesCommitAvailabilitySelectionResult, UnifiedBookingSalesDiscountResult, UnifiedBookingSalesLoadProductsByScheduleDateParams, UnifiedBookingSalesLoadOpenDataParams, UnifiedBookingSalesPrepareAvailabilityProjectionParams, UnifiedBookingSalesPolicyResponse, UnifiedBookingSalesResolveProductAllergyRequirementParams, UnifiedBookingSalesStageRetailProductsParams, UnifiedBookingSalesState } from './types';
|
|
8
8
|
import { BookingTicket } from '../BookingTicket';
|
|
9
|
+
import type { AllergyRequirement } from '../../model/strategy/adapter/itemRule';
|
|
9
10
|
export * from './types';
|
|
10
11
|
export { AvailabilityError } from '../../modules/ResourcePlanner';
|
|
11
12
|
/**
|
|
@@ -73,6 +74,9 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
73
74
|
private availabilityRemoteResourceQuerySequence;
|
|
74
75
|
private availabilityRemoteResourceEpoch;
|
|
75
76
|
private availabilityCommitLocks;
|
|
77
|
+
private allergyItemRuleEvaluator;
|
|
78
|
+
private allergyItemRuleConfigs;
|
|
79
|
+
private allergyItemRuleConfigsPromise;
|
|
76
80
|
initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
|
|
77
81
|
protected getSubmitOrderSalesChannel(): string;
|
|
78
82
|
private createAvailabilityFacadeError;
|
|
@@ -144,6 +148,14 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
144
148
|
*/
|
|
145
149
|
loadOpenData(params: UnifiedBookingSalesLoadOpenDataParams): Promise<OpenDataConfig>;
|
|
146
150
|
getOpenData(): Promise<OpenDataConfig | null>;
|
|
151
|
+
private resetAllergyItemRuleState;
|
|
152
|
+
private fetchAllergyItemRuleConfigs;
|
|
153
|
+
private ensureAllergyItemRuleConfigsLoaded;
|
|
154
|
+
/**
|
|
155
|
+
* 评估当前渠道与商品是否命中 ALLERGY_CHECK。
|
|
156
|
+
* 只返回优先级最高 Action 中当前商品 Target 的 dataSource,不跨商品或 Action 合并。
|
|
157
|
+
*/
|
|
158
|
+
resolveProductAllergyRequirement(params: UnifiedBookingSalesResolveProductAllergyRequirementParams): Promise<AllergyRequirement | null>;
|
|
147
159
|
clearOpenDataCache(): void;
|
|
148
160
|
getInvoiceLayoutConfig(): Promise<InvoiceLayoutConfig>;
|
|
149
161
|
getInvoiceTemplateSettings(): Promise<InvoiceTemplateSettings>;
|
|
@@ -160,6 +172,7 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
160
172
|
callback?: (result: any) => void;
|
|
161
173
|
subscriberId?: string;
|
|
162
174
|
}): Promise<ProductData[]>;
|
|
175
|
+
queryProducts(params?: ProductListStoreQueryParams): Promise<ProductData[]>;
|
|
163
176
|
/** Date-first entry point. It delegates protocol details and cache ownership to ScheduleModule. */
|
|
164
177
|
loadScheduleAvailableDate(params: LoadScheduleAvailableDateParams): Promise<import("../../modules/Date/types").ITime[]>;
|
|
165
178
|
/**
|
|
@@ -52,6 +52,7 @@ var _remoteOccupancyCache = require("./remoteOccupancyCache");
|
|
|
52
52
|
var _BookingTicket = require("../BookingTicket");
|
|
53
53
|
var _localClock = require("../../modules/ResourcePlanner/localClock");
|
|
54
54
|
var _platform = require("../../utils/platform");
|
|
55
|
+
var _itemRule = require("../../model/strategy/adapter/itemRule");
|
|
55
56
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
56
57
|
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'basic', 'checkout', 'availability', 'documents'];
|
|
57
58
|
const OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
|
|
@@ -84,6 +85,22 @@ function getCandidateStartTime(candidate) {
|
|
|
84
85
|
return undefined;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
88
|
+
function normalizePositiveIntegerList(value) {
|
|
89
|
+
if (!Array.isArray(value)) return [];
|
|
90
|
+
return Array.from(new Set(value.map(item => normalizePositiveInteger(item)).filter(item => item !== undefined)));
|
|
91
|
+
}
|
|
92
|
+
function toConfiguredBoolean(value) {
|
|
93
|
+
if (typeof value === 'boolean') return value;
|
|
94
|
+
if (typeof value === 'number') return value !== 0;
|
|
95
|
+
if (typeof value === 'string') {
|
|
96
|
+
return ['1', 'true', 'yes', 'y', 'on'].includes(value.trim().toLowerCase());
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
function normalizeItemRuleStrategyConfigs(value) {
|
|
101
|
+
if (!Array.isArray(value)) return [];
|
|
102
|
+
return value.filter(config => Boolean(config && typeof config === 'object' && config.metadata?.type === 'item_rule'));
|
|
103
|
+
}
|
|
87
104
|
function isRecord(value) {
|
|
88
105
|
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
89
106
|
}
|
|
@@ -1197,11 +1214,15 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1197
1214
|
availabilityRemoteResourceQuerySequence = 0;
|
|
1198
1215
|
availabilityRemoteResourceEpoch = 0;
|
|
1199
1216
|
availabilityCommitLocks = new Set();
|
|
1217
|
+
allergyItemRuleEvaluator = new _itemRule.ItemRuleEvaluator();
|
|
1218
|
+
allergyItemRuleConfigs = [];
|
|
1219
|
+
allergyItemRuleConfigsPromise = null;
|
|
1200
1220
|
async initialize(core, options = {}) {
|
|
1201
1221
|
this.availabilityScheduleCatalog = null;
|
|
1202
1222
|
this.openDataTarget = null;
|
|
1203
1223
|
this.availabilityRuntimeOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)();
|
|
1204
1224
|
this.clearAvailabilityRemoteResourceState();
|
|
1225
|
+
this.resetAllergyItemRuleState();
|
|
1205
1226
|
await super.initialize(core, options);
|
|
1206
1227
|
const openDataBusinessCode = String(this.otherParams?.businessCode ?? this.otherParams?.business_code ?? '').trim();
|
|
1207
1228
|
const openDataChannel = String(this.otherParams?.channel ?? '').trim();
|
|
@@ -1346,6 +1367,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1346
1367
|
cover = false
|
|
1347
1368
|
} = {}) {
|
|
1348
1369
|
const previousScope = this.getAvailabilityScopeDescriptor(this.otherParams || {});
|
|
1370
|
+
const previousItemRuleConfig = this.otherParams?.itemRule;
|
|
1349
1371
|
const explicitlySetsOpenData = Object.prototype.hasOwnProperty.call(params, 'openData');
|
|
1350
1372
|
await super.setOtherParams(params, {
|
|
1351
1373
|
cover
|
|
@@ -1358,11 +1380,15 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1358
1380
|
if (shouldResetAvailabilityState) {
|
|
1359
1381
|
await this.resetAvailabilityProjectionState('set_other_params_reset');
|
|
1360
1382
|
}
|
|
1383
|
+
if (shouldResetAvailabilityState || explicitlySetsOpenData || previousItemRuleConfig !== this.otherParams?.itemRule) {
|
|
1384
|
+
this.resetAllergyItemRuleState();
|
|
1385
|
+
}
|
|
1361
1386
|
}
|
|
1362
1387
|
async destroy() {
|
|
1363
1388
|
this.availabilityScheduleCatalog = null;
|
|
1364
1389
|
this.availabilityRuntimeOffsetMinutes = null;
|
|
1365
1390
|
await this.resetAvailabilityProjectionState('destroy');
|
|
1391
|
+
this.resetAllergyItemRuleState();
|
|
1366
1392
|
await super.destroy();
|
|
1367
1393
|
}
|
|
1368
1394
|
createAvailabilityContextId() {
|
|
@@ -1721,6 +1747,98 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1721
1747
|
channel
|
|
1722
1748
|
});
|
|
1723
1749
|
}
|
|
1750
|
+
resetAllergyItemRuleState() {
|
|
1751
|
+
this.allergyItemRuleConfigs = [];
|
|
1752
|
+
this.allergyItemRuleConfigsPromise = null;
|
|
1753
|
+
this.allergyItemRuleEvaluator.setStrategyConfigs([]);
|
|
1754
|
+
}
|
|
1755
|
+
async fetchAllergyItemRuleConfigs(strategyModelIds) {
|
|
1756
|
+
if (!strategyModelIds.length) return [];
|
|
1757
|
+
try {
|
|
1758
|
+
const response = await this.request.get('/promotion', {
|
|
1759
|
+
skip: 1,
|
|
1760
|
+
num: 99,
|
|
1761
|
+
status: 'active',
|
|
1762
|
+
ids: strategyModelIds
|
|
1763
|
+
});
|
|
1764
|
+
if (response?.code !== 200 || !Array.isArray(response?.data?.list)) {
|
|
1765
|
+
throw new Error('[UnifiedBookingSales] 商品过敏策略加载失败');
|
|
1766
|
+
}
|
|
1767
|
+
const list = response.data.list;
|
|
1768
|
+
return normalizeItemRuleStrategyConfigs(list.map(item => item?.metadata));
|
|
1769
|
+
} catch (error) {
|
|
1770
|
+
// this.logMethodError('fetchAllergyItemRuleConfigs', error, {
|
|
1771
|
+
// strategyModelIds,
|
|
1772
|
+
// });
|
|
1773
|
+
throw error;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
async ensureAllergyItemRuleConfigsLoaded() {
|
|
1777
|
+
if (this.allergyItemRuleConfigs.length > 0) {
|
|
1778
|
+
return this.allergyItemRuleConfigs;
|
|
1779
|
+
}
|
|
1780
|
+
if (this.allergyItemRuleConfigsPromise) {
|
|
1781
|
+
return this.allergyItemRuleConfigsPromise;
|
|
1782
|
+
}
|
|
1783
|
+
this.allergyItemRuleConfigsPromise = (async () => {
|
|
1784
|
+
const staticConfigs = normalizeItemRuleStrategyConfigs(this.otherParams?.itemRule?.strategyConfigs);
|
|
1785
|
+
if (staticConfigs.length > 0) {
|
|
1786
|
+
this.allergyItemRuleConfigs = staticConfigs;
|
|
1787
|
+
this.allergyItemRuleEvaluator.setStrategyConfigs(staticConfigs);
|
|
1788
|
+
return staticConfigs;
|
|
1789
|
+
}
|
|
1790
|
+
const openData = await this.getOpenData();
|
|
1791
|
+
const enabled = toConfiguredBoolean(openData?.['sale.enable_item_rules']);
|
|
1792
|
+
const strategyModelIds = normalizePositiveIntegerList(openData?.['sale.enabled_item_rules']);
|
|
1793
|
+
if (!enabled || !strategyModelIds.length) {
|
|
1794
|
+
this.allergyItemRuleEvaluator.setStrategyConfigs([]);
|
|
1795
|
+
return [];
|
|
1796
|
+
}
|
|
1797
|
+
const loaded = await this.fetchAllergyItemRuleConfigs(strategyModelIds);
|
|
1798
|
+
this.allergyItemRuleConfigs = loaded;
|
|
1799
|
+
this.allergyItemRuleEvaluator.setStrategyConfigs(loaded);
|
|
1800
|
+
return loaded;
|
|
1801
|
+
})();
|
|
1802
|
+
return this.allergyItemRuleConfigsPromise;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
/**
|
|
1806
|
+
* 评估当前渠道与商品是否命中 ALLERGY_CHECK。
|
|
1807
|
+
* 只返回优先级最高 Action 中当前商品 Target 的 dataSource,不跨商品或 Action 合并。
|
|
1808
|
+
*/
|
|
1809
|
+
async resolveProductAllergyRequirement(params) {
|
|
1810
|
+
const productId = normalizePositiveInteger(params.productId);
|
|
1811
|
+
if (!productId) return null;
|
|
1812
|
+
const strategyConfigs = await this.ensureAllergyItemRuleConfigsLoaded();
|
|
1813
|
+
if (!strategyConfigs.length) return null;
|
|
1814
|
+
const productVariantId = normalizePositiveInteger(params.productVariantId);
|
|
1815
|
+
const runtimeConfig = this.otherParams?.itemRule || {};
|
|
1816
|
+
const runtimePax = runtimeConfig.pax || {};
|
|
1817
|
+
const cartItems = (this.getOrderProducts?.() || []).map(item => ({
|
|
1818
|
+
product_id: Number(item?.product_id ?? item?.id),
|
|
1819
|
+
product_variant_id: Number(item?.product_variant_id ?? 0) || undefined,
|
|
1820
|
+
quantity: Number(item?.num ?? item?.quantity ?? 0)
|
|
1821
|
+
})).filter(item => Number.isFinite(item.product_id) && item.product_id > 0 && Number.isFinite(item.quantity) && item.quantity > 0);
|
|
1822
|
+
return this.allergyItemRuleEvaluator.getAllergyRequirement({
|
|
1823
|
+
pax: {
|
|
1824
|
+
total: Number(runtimePax.total ?? 0) || 0,
|
|
1825
|
+
adult: Number(runtimePax.adult ?? 0) || 0,
|
|
1826
|
+
child: Number(runtimePax.child ?? 0) || 0
|
|
1827
|
+
},
|
|
1828
|
+
cartItems,
|
|
1829
|
+
serviceType: String(runtimeConfig.serviceType ?? this.otherParams?.serviceType ?? ''),
|
|
1830
|
+
channel: String(params.channel ?? this.otherParams?.channel ?? this.otherParams?.platform ?? ''),
|
|
1831
|
+
currentProduct: {
|
|
1832
|
+
product_id: productId,
|
|
1833
|
+
...(productVariantId ? {
|
|
1834
|
+
product_variant_id: productVariantId
|
|
1835
|
+
} : {})
|
|
1836
|
+
},
|
|
1837
|
+
submissionIndex: Number(runtimeConfig.submissionIndex ?? 0) || 0,
|
|
1838
|
+
strategyConfigs,
|
|
1839
|
+
custom: runtimeConfig.custom
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1724
1842
|
clearOpenDataCache() {
|
|
1725
1843
|
this.openDataTarget = null;
|
|
1726
1844
|
this.loadOpenDataInFlight = null;
|
|
@@ -1783,6 +1901,10 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1783
1901
|
await this.core.effects.emit(`${this.name}:onProductsLoaded`, result);
|
|
1784
1902
|
return result;
|
|
1785
1903
|
}
|
|
1904
|
+
async queryProducts(params = {}) {
|
|
1905
|
+
if (!this.store.products) throw new Error('[UnifiedBookingSales] products 模块未初始化');
|
|
1906
|
+
return this.store.products.queryProducts(params);
|
|
1907
|
+
}
|
|
1786
1908
|
|
|
1787
1909
|
/** Date-first entry point. It delegates protocol details and cache ownership to ScheduleModule. */
|
|
1788
1910
|
async loadScheduleAvailableDate(params) {
|
|
@@ -3333,7 +3455,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
3333
3455
|
} else {
|
|
3334
3456
|
const beforeProductLineUids = new Set((this.getTempOrder()?.products || []).map(line => getProductLineUid(line)).filter(Boolean));
|
|
3335
3457
|
const beforeBookingUids = new Set((this.getTempOrder()?.bookings || []).map(item => getBookingUid(item)).filter(Boolean));
|
|
3336
|
-
const products = await this.addProductToOrder(transformed, booking
|
|
3458
|
+
const products = await this.addProductToOrder(transformed, booking, params.salesNotes?.length ? {
|
|
3459
|
+
salesNotes: params.salesNotes
|
|
3460
|
+
} : undefined);
|
|
3337
3461
|
const addedLines = products.filter(line => sameAvailabilityId(line.product_id ?? line.id, refreshedCandidate.productId) && line.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeProductLineUids.has(getProductLineUid(line)));
|
|
3338
3462
|
productLineUids = addedLines.map(line => getProductLineUid(line)).filter(Boolean);
|
|
3339
3463
|
const addedBookings = (this.getTempOrder()?.bookings || []).filter(item => item.metadata?.availability_candidate_key === refreshedCandidate.key && !beforeBookingUids.has(getBookingUid(item)));
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { InvoiceLayoutConfig, InvoiceTemplateSettings, OpenDataConfig } from '../../modules/OpenData';
|
|
2
|
-
import type { ProductListLoadProductsParams } from '../../modules/ProductList';
|
|
2
|
+
import type { ProductListLoadProductsParams, ProductListStoreQueryParams } from '../../modules/ProductList';
|
|
3
|
+
import type { ProductData } from '../../modules/Product/types';
|
|
3
4
|
import type { LoadScheduleAvailableDateParams } from '../../modules/Schedule/types';
|
|
4
5
|
import type { AvailabilityDateRange, AvailabilityErrorCode, AvailabilityId, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProjection, AvailabilityQuery, AvailabilityRequirementSelection, AvailabilityResource, AvailabilitySelectionValidationResult, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, ResourceAvailabilityGroup, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem } from '../../modules/ResourcePlanner';
|
|
5
6
|
import type { BookingTicketState } from '../BookingTicket/types';
|
|
7
|
+
import type { AllergyRequirement } from '../../model/strategy/adapter/itemRule';
|
|
8
|
+
import type { SalesNoteDraftInput } from '../../modules/Order/types';
|
|
9
|
+
export type { ProductListStoreQueryParams } from '../../modules/ProductList';
|
|
6
10
|
export type { AvailabilityAbsoluteRange, AvailabilityAssignment, AvailabilityCell, AvailabilityDateRange, AvailabilityDisplayRange, AvailabilityErrorCode, AvailabilityId, AvailabilityMode, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProductKind, AvailabilityProjection, AvailabilityProjectionInput, AvailabilityProjectionMeta, AvailabilityQuery, AvailabilityQueryResult, AvailabilityRequirementGroup, AvailabilityRequirementGroupResult, AvailabilityRequirementSelection, AvailabilityResource, AvailabilityResourceOption, AvailabilityResourceType, AvailabilityResourceWindow, AvailabilityScheduleMode, AvailabilityScheduleRef, AvailabilityScheduleRule, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, AvailabilitySessionRange, AvailabilityStatus, DateAvailabilityGroup, DateAvailabilityItem, DateAvailabilityQuery, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityGroup, ProductAvailabilityItem, ProductAvailabilityQuery, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, QueryAvailabilityBaseRequest, ResourceAvailabilityGroup, ResourceAvailabilityQuery, ResourceAvailabilityQueryResult, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem, TimeAvailabilityQuery, TimeAvailabilityQueryResult, } from '../../modules/ResourcePlanner';
|
|
7
11
|
export interface UnifiedBookingSalesState extends BookingTicketState {
|
|
8
12
|
}
|
|
@@ -24,6 +28,12 @@ export declare enum UnifiedBookingSalesHooks {
|
|
|
24
28
|
export interface UnifiedBookingSalesOtherParams extends Record<string, any> {
|
|
25
29
|
enableSessionStoragePersist?: boolean;
|
|
26
30
|
}
|
|
31
|
+
export type UnifiedBookingSalesAllergyRequirement = AllergyRequirement;
|
|
32
|
+
export interface UnifiedBookingSalesResolveProductAllergyRequirementParams {
|
|
33
|
+
productId: number | string;
|
|
34
|
+
productVariantId?: number | string;
|
|
35
|
+
channel?: string;
|
|
36
|
+
}
|
|
27
37
|
export interface UnifiedBookingSalesLoadOpenDataParams {
|
|
28
38
|
businessCode: string;
|
|
29
39
|
channel: string;
|
|
@@ -151,6 +161,8 @@ export interface ContextualCommitAvailabilitySelectionParams {
|
|
|
151
161
|
requirementSelections: AvailabilityRequirementSelection[];
|
|
152
162
|
partySize: number;
|
|
153
163
|
bookingCount?: number;
|
|
164
|
+
/** 新增商品行时与商品、预约在同一次 Order mutation 内写入的 Sales Notes。 */
|
|
165
|
+
salesNotes?: SalesNoteDraftInput[];
|
|
154
166
|
/** 编辑预约时,允许本次显式报价覆盖已落库订单行的历史价格。 */
|
|
155
167
|
allowBookingReprice?: boolean;
|
|
156
168
|
/** 编辑预约重报价后,允许订单模块重新应用已选编辑态折扣。 */
|
|
@@ -214,6 +226,7 @@ export interface UnifiedBookingSalesApi {
|
|
|
214
226
|
/** Date-first calendar availability backed by ScheduleModule. */
|
|
215
227
|
loadScheduleAvailableDate: (params: LoadScheduleAvailableDateParams) => Promise<unknown>;
|
|
216
228
|
loadProductsByScheduleDate: (params: UnifiedBookingSalesLoadProductsByScheduleDateParams) => Promise<unknown[]>;
|
|
229
|
+
queryProducts: (params?: ProductListStoreQueryParams) => Promise<ProductData[]>;
|
|
217
230
|
stageRetailProducts: (params: UnifiedBookingSalesStageRetailProductsParams) => Promise<Record<string, any> | null>;
|
|
218
231
|
addRetailProduct: (params: UnifiedBookingSalesAddRetailProductParams) => Promise<Record<string, any>[]>;
|
|
219
232
|
prepareAvailabilityProjection: (params: UnifiedBookingSalesPrepareAvailabilityProjectionParams) => Promise<AvailabilityContextRef>;
|
|
@@ -1758,7 +1758,11 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1758
1758
|
return sourceMap;
|
|
1759
1759
|
}
|
|
1760
1760
|
getItemRuleRuntimeConfig() {
|
|
1761
|
-
|
|
1761
|
+
const runtimeConfig = this.itemRuleRuntimeConfig || {};
|
|
1762
|
+
return {
|
|
1763
|
+
...runtimeConfig,
|
|
1764
|
+
channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel ?? this.otherParams?.channel
|
|
1765
|
+
};
|
|
1762
1766
|
}
|
|
1763
1767
|
async ensureItemRuleConfigsLoaded() {
|
|
1764
1768
|
if (this.itemRuleConfigs.length > 0) return this.itemRuleConfigs;
|