@pisell/pisellos 2.3.83 → 2.3.85
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/modules/Quotation/index.d.ts +16 -0
- package/dist/modules/Quotation/index.js +241 -32
- package/dist/server/index.js +1 -1
- package/dist/solution/BaseSales/index.js +92 -72
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/VenueBooking/index.d.ts +2 -0
- package/dist/solution/VenueBooking/index.js +542 -494
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/dist/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/lib/modules/Quotation/index.d.ts +16 -0
- package/lib/modules/Quotation/index.js +117 -11
- package/lib/server/index.js +1 -1
- package/lib/solution/BaseSales/index.js +25 -9
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/VenueBooking/index.d.ts +2 -0
- package/lib/solution/VenueBooking/index.js +28 -8
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
- package/lib/solution/VenueBooking/utils/dateSummary.js +3 -1
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +2 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +3 -1
- package/package.json +1 -1
|
@@ -7,5 +7,6 @@ export declare function buildDateRangeSummary(params: {
|
|
|
7
7
|
rawResources: VenueResourceRawData[];
|
|
8
8
|
resourceProductMap: Map<number | string, ResourceProductMapping[]>;
|
|
9
9
|
quotationModule?: QuotationModule;
|
|
10
|
+
channel?: string;
|
|
10
11
|
resolveConfig?: (date: string) => VenueBookingSlotConfig;
|
|
11
12
|
}): VenueDateSummaryItem[];
|
|
@@ -14,6 +14,7 @@ export function buildDateRangeSummary(params) {
|
|
|
14
14
|
rawResources = params.rawResources,
|
|
15
15
|
resourceProductMap = params.resourceProductMap,
|
|
16
16
|
quotationModule = params.quotationModule,
|
|
17
|
+
channel = params.channel,
|
|
17
18
|
resolveConfig = params.resolveConfig;
|
|
18
19
|
var result = [];
|
|
19
20
|
var productIds = quotationModule ? _toConsumableArray(new Set(_toConsumableArray(resourceProductMap.values()).flat().map(function (m) {
|
|
@@ -32,7 +33,8 @@ export function buildDateRangeSummary(params) {
|
|
|
32
33
|
});
|
|
33
34
|
quotationPriceMap = quotationModule.buildProductPriceMap({
|
|
34
35
|
productIds: productIds,
|
|
35
|
-
timePoints: timePoints
|
|
36
|
+
timePoints: timePoints,
|
|
37
|
+
channel: channel
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
var grid = buildTimeSlotGrid({
|
|
@@ -5,10 +5,12 @@ export declare function mergeConsecutiveSlots(slots: VenueSlotSelection[]): Merg
|
|
|
5
5
|
export declare function buildPriceBreakdown(params: {
|
|
6
6
|
group: MergedSlotGroup;
|
|
7
7
|
productId: number;
|
|
8
|
+
channel?: string;
|
|
8
9
|
quotation?: {
|
|
9
10
|
getQuotationShelfId: (p: {
|
|
10
11
|
productId: number;
|
|
11
12
|
datetime: string;
|
|
13
|
+
channel?: string;
|
|
12
14
|
}) => number;
|
|
13
15
|
};
|
|
14
16
|
}): PriceBreakdownEntry[];
|
|
@@ -53,6 +53,7 @@ export function mergeConsecutiveSlots(slots) {
|
|
|
53
53
|
export function buildPriceBreakdown(params) {
|
|
54
54
|
var group = params.group,
|
|
55
55
|
productId = params.productId,
|
|
56
|
+
channel = params.channel,
|
|
56
57
|
quotation = params.quotation;
|
|
57
58
|
if (!group.slots.length) return [];
|
|
58
59
|
var entries = [];
|
|
@@ -64,7 +65,8 @@ export function buildPriceBreakdown(params) {
|
|
|
64
65
|
var unitPrice = Number(slot.price || '0');
|
|
65
66
|
var shelfId = quotation ? quotation.getQuotationShelfId({
|
|
66
67
|
productId: productId,
|
|
67
|
-
datetime: slot.startTime
|
|
68
|
+
datetime: slot.startTime,
|
|
69
|
+
channel: channel
|
|
68
70
|
}) : 0;
|
|
69
71
|
var startHm = dayjs(slot.startTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|
|
70
72
|
var endHm = dayjs(slot.endTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|
|
@@ -11,12 +11,23 @@ export declare class QuotationModule extends BaseModule implements Module {
|
|
|
11
11
|
private scheduleResolver?;
|
|
12
12
|
private app;
|
|
13
13
|
private quotationListUpdatedListener?;
|
|
14
|
+
private quotationCache;
|
|
15
|
+
private quotationLoadPromises;
|
|
16
|
+
private quotationCacheVersions;
|
|
17
|
+
private lifecycleGeneration;
|
|
18
|
+
private activeChannelKey;
|
|
14
19
|
constructor(name?: string, version?: string);
|
|
15
20
|
initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
|
|
16
21
|
loadQuotations(params?: {
|
|
17
22
|
channel?: string;
|
|
18
23
|
customer_id?: number | string;
|
|
19
24
|
}): Promise<void>;
|
|
25
|
+
ensureQuotations(params?: {
|
|
26
|
+
channel?: string;
|
|
27
|
+
customer_id?: number | string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
invalidateQuotationCache(channel?: string): void;
|
|
30
|
+
private fetchQuotations;
|
|
20
31
|
getQuotationList(): QuotationItem[];
|
|
21
32
|
setQuotationListUpdatedListener(listener?: () => void): void;
|
|
22
33
|
getQuotationCustomerScopeInfo(): QuotationCustomerScopeInfo;
|
|
@@ -60,12 +71,17 @@ export declare class QuotationModule extends BaseModule implements Module {
|
|
|
60
71
|
buildProductPriceMap(params: {
|
|
61
72
|
productIds: number[];
|
|
62
73
|
timePoints: string[];
|
|
74
|
+
channel?: string;
|
|
63
75
|
customer_id?: number | string;
|
|
64
76
|
}): Map<string, string | null>;
|
|
65
77
|
setScheduleResolver(resolver: (id: number) => ScheduleItem | undefined): void;
|
|
66
78
|
private applyQuotationResponse;
|
|
67
79
|
private notifyQuotationListUpdated;
|
|
68
80
|
private getQuotationCacheKeyData;
|
|
81
|
+
private normalizeChannel;
|
|
82
|
+
private activateChannel;
|
|
83
|
+
private getQuotationCacheVersion;
|
|
84
|
+
private bumpQuotationCacheVersion;
|
|
69
85
|
private isQuotationVisibleForCustomer;
|
|
70
86
|
private hasValidCustomerId;
|
|
71
87
|
private normalizeCustomerId;
|
|
@@ -16,6 +16,11 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
16
16
|
scheduleResolver;
|
|
17
17
|
app;
|
|
18
18
|
quotationListUpdatedListener;
|
|
19
|
+
quotationCache = new Map();
|
|
20
|
+
quotationLoadPromises = new Map();
|
|
21
|
+
quotationCacheVersions = new Map();
|
|
22
|
+
lifecycleGeneration = 0;
|
|
23
|
+
activeChannelKey = '';
|
|
19
24
|
constructor(name, version) {
|
|
20
25
|
super(name, version);
|
|
21
26
|
}
|
|
@@ -27,17 +32,93 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
27
32
|
this.store = {
|
|
28
33
|
list: []
|
|
29
34
|
};
|
|
35
|
+
this.quotationCache.clear();
|
|
36
|
+
this.quotationLoadPromises.clear();
|
|
37
|
+
this.quotationCacheVersions.clear();
|
|
38
|
+
this.activeChannelKey = '';
|
|
39
|
+
this.lifecycleGeneration += 1;
|
|
30
40
|
}
|
|
31
41
|
async loadQuotations(params) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
const channelKey = this.normalizeChannel(params?.channel);
|
|
43
|
+
const cacheVersion = this.bumpQuotationCacheVersion(channelKey);
|
|
44
|
+
const lifecycleGeneration = this.lifecycleGeneration;
|
|
45
|
+
this.activateChannel(channelKey);
|
|
46
|
+
const loadPromise = this.fetchQuotations({
|
|
47
|
+
channelKey,
|
|
48
|
+
cacheVersion,
|
|
49
|
+
lifecycleGeneration
|
|
50
|
+
});
|
|
51
|
+
this.quotationLoadPromises.set(channelKey, loadPromise);
|
|
52
|
+
try {
|
|
53
|
+
await loadPromise;
|
|
54
|
+
} finally {
|
|
55
|
+
if (this.quotationLoadPromises.get(channelKey) === loadPromise) {
|
|
56
|
+
this.quotationLoadPromises.delete(channelKey);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async ensureQuotations(params) {
|
|
61
|
+
const channelKey = this.normalizeChannel(params?.channel);
|
|
62
|
+
const lifecycleGeneration = this.lifecycleGeneration;
|
|
63
|
+
while (true) {
|
|
64
|
+
if (this.lifecycleGeneration !== lifecycleGeneration) return;
|
|
65
|
+
if (this.quotationCache.has(channelKey)) {
|
|
66
|
+
this.activateChannel(channelKey);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const pending = this.quotationLoadPromises.get(channelKey);
|
|
70
|
+
if (!pending) {
|
|
71
|
+
try {
|
|
72
|
+
await this.loadQuotations(params);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (this.quotationCache.has(channelKey)) {
|
|
75
|
+
this.activateChannel(channelKey);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (this.quotationLoadPromises.has(channelKey)) continue;
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const cacheVersion = this.getQuotationCacheVersion(channelKey);
|
|
84
|
+
try {
|
|
85
|
+
await pending;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
const latestPending = this.quotationLoadPromises.get(channelKey);
|
|
88
|
+
if (latestPending && latestPending !== pending) continue;
|
|
89
|
+
if (this.getQuotationCacheVersion(channelKey) !== cacheVersion) continue;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
if (this.quotationCache.has(channelKey)) {
|
|
93
|
+
this.activateChannel(channelKey);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const latestPending = this.quotationLoadPromises.get(channelKey);
|
|
97
|
+
if (latestPending && latestPending !== pending) continue;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
invalidateQuotationCache(channel) {
|
|
101
|
+
if (channel !== undefined) {
|
|
102
|
+
const channelKey = this.normalizeChannel(channel);
|
|
103
|
+
this.bumpQuotationCacheVersion(channelKey);
|
|
104
|
+
this.quotationCache.delete(channelKey);
|
|
105
|
+
this.quotationLoadPromises.delete(channelKey);
|
|
106
|
+
if (this.activeChannelKey === channelKey) this.store.list = [];
|
|
107
|
+
return;
|
|
36
108
|
}
|
|
109
|
+
const channelKeys = new Set([...this.quotationCache.keys(), ...this.quotationLoadPromises.keys(), ...this.quotationCacheVersions.keys(), this.activeChannelKey]);
|
|
110
|
+
channelKeys.forEach(channelKey => this.bumpQuotationCacheVersion(channelKey));
|
|
111
|
+
this.quotationCache.clear();
|
|
112
|
+
this.quotationLoadPromises.clear();
|
|
113
|
+
this.store.list = [];
|
|
114
|
+
}
|
|
115
|
+
async fetchQuotations(params) {
|
|
116
|
+
const query = {};
|
|
117
|
+
if (params.channelKey) query.channel = params.channelKey;
|
|
37
118
|
let initialResultApplied = false;
|
|
38
119
|
const applyRemoteUpdate = response => {
|
|
39
|
-
this.applyQuotationResponse(response);
|
|
40
|
-
if (initialResultApplied) {
|
|
120
|
+
const applied = this.applyQuotationResponse(response, params);
|
|
121
|
+
if (applied && initialResultApplied && this.activeChannelKey === params.channelKey) {
|
|
41
122
|
this.notifyQuotationListUpdated();
|
|
42
123
|
}
|
|
43
124
|
};
|
|
@@ -49,7 +130,7 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
49
130
|
},
|
|
50
131
|
cacheUpdateChange: applyRemoteUpdate
|
|
51
132
|
});
|
|
52
|
-
this.applyQuotationResponse(res);
|
|
133
|
+
this.applyQuotationResponse(res, params);
|
|
53
134
|
initialResultApplied = true;
|
|
54
135
|
}
|
|
55
136
|
getQuotationList() {
|
|
@@ -109,7 +190,8 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
109
190
|
datetime,
|
|
110
191
|
customer_id
|
|
111
192
|
} = params;
|
|
112
|
-
|
|
193
|
+
const quotations = params.channel === undefined ? this.store.list : this.quotationCache.get(this.normalizeChannel(params.channel)) || [];
|
|
194
|
+
for (const quotation of quotations) {
|
|
113
195
|
const visible = this.isQuotationVisibleForCustomer(quotation, customer_id);
|
|
114
196
|
if (!visible) continue;
|
|
115
197
|
const active = this.isQuotationActiveAt(quotation, datetime);
|
|
@@ -135,13 +217,15 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
135
217
|
*/
|
|
136
218
|
buildProductPriceMap(params) {
|
|
137
219
|
const map = new Map();
|
|
138
|
-
|
|
220
|
+
const quotations = params.channel === undefined ? this.store.list : this.quotationCache.get(this.normalizeChannel(params.channel)) || [];
|
|
221
|
+
if (!quotations.length) return map;
|
|
139
222
|
for (const productId of params.productIds) {
|
|
140
223
|
for (const timePoint of params.timePoints) {
|
|
141
224
|
const key = `${productId}:${timePoint}`;
|
|
142
225
|
const price = this.getPriceForProduct({
|
|
143
226
|
productId,
|
|
144
227
|
datetime: timePoint,
|
|
228
|
+
channel: params.channel,
|
|
145
229
|
customer_id: params.customer_id
|
|
146
230
|
});
|
|
147
231
|
if (price !== null) {
|
|
@@ -154,9 +238,15 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
154
238
|
setScheduleResolver(resolver) {
|
|
155
239
|
this.scheduleResolver = resolver;
|
|
156
240
|
}
|
|
157
|
-
applyQuotationResponse(response) {
|
|
241
|
+
applyQuotationResponse(response, params) {
|
|
158
242
|
const source = response?.data?.list || response?.list || [];
|
|
159
|
-
|
|
243
|
+
const list = [...source].sort((a, b) => Number(b.sort || 0) - Number(a.sort || 0));
|
|
244
|
+
if (this.lifecycleGeneration !== params.lifecycleGeneration || this.getQuotationCacheVersion(params.channelKey) !== params.cacheVersion) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
this.quotationCache.set(params.channelKey, list);
|
|
248
|
+
if (this.activeChannelKey === params.channelKey) this.store.list = list;
|
|
249
|
+
return true;
|
|
160
250
|
}
|
|
161
251
|
notifyQuotationListUpdated() {
|
|
162
252
|
try {
|
|
@@ -179,6 +269,22 @@ class QuotationModule extends _BaseModule.BaseModule {
|
|
|
179
269
|
shop_id: shopId
|
|
180
270
|
};
|
|
181
271
|
}
|
|
272
|
+
normalizeChannel(channel) {
|
|
273
|
+
const normalized = channel?.trim().toLowerCase() || '';
|
|
274
|
+
return normalized === 'online_store' ? 'online-store' : normalized;
|
|
275
|
+
}
|
|
276
|
+
activateChannel(channelKey) {
|
|
277
|
+
this.activeChannelKey = channelKey;
|
|
278
|
+
this.store.list = this.quotationCache.get(channelKey) || [];
|
|
279
|
+
}
|
|
280
|
+
getQuotationCacheVersion(channelKey) {
|
|
281
|
+
return this.quotationCacheVersions.get(channelKey) || 0;
|
|
282
|
+
}
|
|
283
|
+
bumpQuotationCacheVersion(channelKey) {
|
|
284
|
+
const nextVersion = this.getQuotationCacheVersion(channelKey) + 1;
|
|
285
|
+
this.quotationCacheVersions.set(channelKey, nextVersion);
|
|
286
|
+
return nextVersion;
|
|
287
|
+
}
|
|
182
288
|
isQuotationVisibleForCustomer(quotation, customerId) {
|
|
183
289
|
const customers = quotation.customer || [];
|
|
184
290
|
if (customers.length === 0) return true;
|
package/lib/server/index.js
CHANGED
|
@@ -1481,7 +1481,7 @@ class Server {
|
|
|
1481
1481
|
// timerIds.push(timerId);
|
|
1482
1482
|
// }
|
|
1483
1483
|
setInterval(() => {
|
|
1484
|
-
const currentTime = (0, _dayjs.default)().format('
|
|
1484
|
+
const currentTime = (0, _dayjs.default)().format('HH:mm');
|
|
1485
1485
|
if (timePoints.includes(currentTime)) {
|
|
1486
1486
|
this.onScheduleTimePointTimerFire(subscriberId);
|
|
1487
1487
|
}
|
|
@@ -639,8 +639,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
639
639
|
async loadQuotationForPriceQuery(params) {
|
|
640
640
|
if (!params.quotation) return;
|
|
641
641
|
this.applyQuotationScheduleResolver(params.quotation);
|
|
642
|
-
|
|
643
|
-
|
|
642
|
+
const quotation = params.quotation;
|
|
643
|
+
const load = typeof quotation.ensureQuotations === 'function' ? quotation.ensureQuotations.bind(quotation) : quotation.loadQuotations.bind(quotation);
|
|
644
|
+
await load({
|
|
645
|
+
channel: this.getPriceQueryChannel(params.channel),
|
|
644
646
|
customer_id: params.customer_id
|
|
645
647
|
});
|
|
646
648
|
}
|
|
@@ -3153,22 +3155,24 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3153
3155
|
const quotation = useCustomerUserPricing ? undefined : this.store.quotation;
|
|
3154
3156
|
const customerId = params.customer_id ?? this.getCurrentOrderCustomerId();
|
|
3155
3157
|
await this.prepareProductPriceQueryContext(customerId);
|
|
3158
|
+
const channel = this.getPriceQueryChannel(params.channel);
|
|
3156
3159
|
const [authoritativeProduct] = await this.resolveProductsForPriceQuery({
|
|
3157
3160
|
priceQueries: [params],
|
|
3158
3161
|
schedule: this.getPriceQuerySchedule(params),
|
|
3159
3162
|
customerId,
|
|
3160
|
-
channel
|
|
3163
|
+
channel
|
|
3161
3164
|
});
|
|
3162
3165
|
const product = this.mergeProductForPriceQuery(params.product, authoritativeProduct);
|
|
3163
3166
|
if (!useCustomerUserPricing) {
|
|
3164
3167
|
await this.loadQuotationForPriceQuery({
|
|
3165
3168
|
quotation,
|
|
3166
3169
|
customer_id: customerId,
|
|
3167
|
-
channel
|
|
3170
|
+
channel
|
|
3168
3171
|
});
|
|
3169
3172
|
}
|
|
3170
3173
|
return (0, _quotationPrice.calculateBaseSalesProductBookingPrice)({
|
|
3171
3174
|
...params,
|
|
3175
|
+
channel,
|
|
3172
3176
|
product,
|
|
3173
3177
|
fallback_price: authoritativeProduct ? undefined : params.fallback_price,
|
|
3174
3178
|
customer_id: customerId,
|
|
@@ -3242,11 +3246,12 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3242
3246
|
const useCustomerUserPricing = this.isCustomerUserPriceQuery();
|
|
3243
3247
|
const quotation = useCustomerUserPricing ? undefined : this.store.quotation;
|
|
3244
3248
|
const currentOrderCustomerId = this.getCurrentOrderCustomerId();
|
|
3249
|
+
const resolvedChannels = paramsList.map(params => this.getPriceQueryChannel(params.channel));
|
|
3245
3250
|
const authoritativeProducts = paramsList.map(() => null);
|
|
3246
3251
|
const groups = new Map();
|
|
3247
3252
|
paramsList.forEach((params, index) => {
|
|
3248
3253
|
const schedule = this.getPriceQuerySchedule(params);
|
|
3249
|
-
const channel =
|
|
3254
|
+
const channel = resolvedChannels[index];
|
|
3250
3255
|
const customerId = params.customer_id ?? currentOrderCustomerId;
|
|
3251
3256
|
const groupKey = [schedule.schedule_date, schedule.schedule_datetime, channel || '', this.normalizePriceContextCustomerId(customerId) || ''].join('|');
|
|
3252
3257
|
const group = groups.get(groupKey) || {
|
|
@@ -3272,19 +3277,30 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
3272
3277
|
});
|
|
3273
3278
|
}));
|
|
3274
3279
|
if (!useCustomerUserPricing) {
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
channel
|
|
3280
|
+
const quotationContexts = new Map();
|
|
3281
|
+
paramsList.forEach((params, index) => {
|
|
3282
|
+
const channel = resolvedChannels[index];
|
|
3283
|
+
const key = channel || '';
|
|
3284
|
+
if (quotationContexts.has(key)) return;
|
|
3285
|
+
quotationContexts.set(key, {
|
|
3286
|
+
channel,
|
|
3287
|
+
customer_id: params.customer_id ?? currentOrderCustomerId
|
|
3288
|
+
});
|
|
3279
3289
|
});
|
|
3290
|
+
await Promise.all(Array.from(quotationContexts.values()).map(context => this.loadQuotationForPriceQuery({
|
|
3291
|
+
quotation,
|
|
3292
|
+
...context
|
|
3293
|
+
})));
|
|
3280
3294
|
}
|
|
3281
3295
|
return paramsList.map((params, index) => {
|
|
3282
3296
|
const productInput = params.product || {};
|
|
3283
3297
|
const authoritativeProduct = authoritativeProducts[index];
|
|
3284
3298
|
const product = this.mergeProductForPriceQuery(productInput, authoritativeProduct);
|
|
3285
3299
|
const customerId = params.customer_id ?? currentOrderCustomerId;
|
|
3300
|
+
const channel = resolvedChannels[index];
|
|
3286
3301
|
return (0, _quotationPrice.calculateBaseSalesProductBookingPrice)({
|
|
3287
3302
|
...params,
|
|
3303
|
+
channel,
|
|
3288
3304
|
product,
|
|
3289
3305
|
fallback_price: authoritativeProduct ? undefined : params.fallback_price,
|
|
3290
3306
|
customer_id: customerId,
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 |
|
|
329
|
+
weekNum: 0 | 1 | 2 | 5 | 3 | 4 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "sold_out" | "lots_of_space" | "filling_up_fast";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -334,7 +334,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
334
334
|
* 获取当前的客户搜索条件
|
|
335
335
|
* @returns 当前搜索条件
|
|
336
336
|
*/
|
|
337
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
337
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
|
|
338
338
|
/**
|
|
339
339
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
340
340
|
* @returns 客户状态
|
|
@@ -90,6 +90,8 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
|
|
|
90
90
|
loadAddonProducts(): Promise<ProductData[]>;
|
|
91
91
|
getVenueProducts(): ProductData[];
|
|
92
92
|
getAddonProductsList(): ProductData[];
|
|
93
|
+
private ensureQuotationsLoaded;
|
|
94
|
+
private preloadQuotations;
|
|
93
95
|
loadQuotations(params?: {
|
|
94
96
|
channel?: string;
|
|
95
97
|
}): Promise<void>;
|
|
@@ -370,7 +370,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
370
370
|
});
|
|
371
371
|
}
|
|
372
372
|
if (this.store.quotation) {
|
|
373
|
-
await this.
|
|
373
|
+
await this.ensureQuotationsLoaded({
|
|
374
374
|
channel: this.otherParams?.channel
|
|
375
375
|
});
|
|
376
376
|
}
|
|
@@ -566,7 +566,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
566
566
|
if (this.store.schedule) {
|
|
567
567
|
await this.store.schedule.loadAllSchedule();
|
|
568
568
|
this.injectScheduleResolverToQuotation();
|
|
569
|
-
this.
|
|
569
|
+
this.preloadQuotations({
|
|
570
570
|
channel: this.otherParams?.channel
|
|
571
571
|
});
|
|
572
572
|
}
|
|
@@ -720,6 +720,19 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
720
720
|
|
|
721
721
|
// ─── 报价单 ───
|
|
722
722
|
|
|
723
|
+
async ensureQuotationsLoaded(params) {
|
|
724
|
+
const quotation = this.store.quotation;
|
|
725
|
+
if (!quotation) return;
|
|
726
|
+
const load = typeof quotation.ensureQuotations === 'function' ? quotation.ensureQuotations.bind(quotation) : quotation.loadQuotations.bind(quotation);
|
|
727
|
+
await load(params);
|
|
728
|
+
}
|
|
729
|
+
preloadQuotations(params) {
|
|
730
|
+
void this.ensureQuotationsLoaded(params).catch(error => {
|
|
731
|
+
this.logMethodError('preloadQuotations', error, {
|
|
732
|
+
channel: params?.channel
|
|
733
|
+
});
|
|
734
|
+
});
|
|
735
|
+
}
|
|
723
736
|
async loadQuotations(params) {
|
|
724
737
|
this.logMethodStart('loadQuotations');
|
|
725
738
|
try {
|
|
@@ -854,6 +867,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
854
867
|
rawResources: this.store.rawResourceData,
|
|
855
868
|
resourceProductMap: this.resourceProductMap,
|
|
856
869
|
quotationModule: this.store.quotation,
|
|
870
|
+
channel: this.otherParams?.channel,
|
|
857
871
|
resolveConfig: date => this.resolveSlotConfigForDate(date)
|
|
858
872
|
});
|
|
859
873
|
}
|
|
@@ -866,7 +880,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
866
880
|
const timePoints = timeLabels.map(label => `${date} ${label}`);
|
|
867
881
|
quotationPriceMap = this.store.quotation.buildProductPriceMap({
|
|
868
882
|
productIds,
|
|
869
|
-
timePoints
|
|
883
|
+
timePoints,
|
|
884
|
+
channel: this.otherParams?.channel
|
|
870
885
|
});
|
|
871
886
|
}
|
|
872
887
|
return (0, _timeSlot.buildTimeSlotGrid)({
|
|
@@ -1185,7 +1200,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1185
1200
|
price_breakdown: (0, _slotMerge.buildPriceBreakdown)({
|
|
1186
1201
|
group,
|
|
1187
1202
|
productId: mapping.productId,
|
|
1188
|
-
quotation: this.store.quotation
|
|
1203
|
+
quotation: this.store.quotation,
|
|
1204
|
+
channel: this.otherParams?.channel
|
|
1189
1205
|
})
|
|
1190
1206
|
},
|
|
1191
1207
|
_origin: venueProductOrigin
|
|
@@ -1325,7 +1341,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1325
1341
|
productId: mapping.productId,
|
|
1326
1342
|
price: this.store.quotation.getPriceForProduct({
|
|
1327
1343
|
productId: mapping.productId,
|
|
1328
|
-
datetime: slot.startTime
|
|
1344
|
+
datetime: slot.startTime,
|
|
1345
|
+
channel: this.otherParams?.channel
|
|
1329
1346
|
}) ?? mapping.price
|
|
1330
1347
|
}));
|
|
1331
1348
|
const merged = (0, _slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
@@ -1335,14 +1352,16 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1335
1352
|
product.metadata.price_breakdown = (0, _slotMerge.buildPriceBreakdown)({
|
|
1336
1353
|
group: merged[0],
|
|
1337
1354
|
productId: mapping.productId,
|
|
1338
|
-
quotation: this.store.quotation
|
|
1355
|
+
quotation: this.store.quotation,
|
|
1356
|
+
channel: this.otherParams?.channel
|
|
1339
1357
|
});
|
|
1340
1358
|
}
|
|
1341
1359
|
} else if (product.product_id != null) {
|
|
1342
1360
|
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1343
1361
|
productId: product.product_id,
|
|
1344
1362
|
variantId: product.product_variant_id ?? undefined,
|
|
1345
|
-
datetime: now
|
|
1363
|
+
datetime: now,
|
|
1364
|
+
channel: this.otherParams?.channel
|
|
1346
1365
|
});
|
|
1347
1366
|
if (quotationPrice !== null) {
|
|
1348
1367
|
product.selling_price = quotationPrice;
|
|
@@ -1550,7 +1569,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1550
1569
|
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1551
1570
|
productId: product.product_id,
|
|
1552
1571
|
variantId: product.product_variant_id ?? undefined,
|
|
1553
|
-
datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss')
|
|
1572
|
+
datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss'),
|
|
1573
|
+
channel: this.otherParams?.channel
|
|
1554
1574
|
});
|
|
1555
1575
|
if (quotationPrice !== null) {
|
|
1556
1576
|
product.selling_price = quotationPrice;
|
|
@@ -7,5 +7,6 @@ export declare function buildDateRangeSummary(params: {
|
|
|
7
7
|
rawResources: VenueResourceRawData[];
|
|
8
8
|
resourceProductMap: Map<number | string, ResourceProductMapping[]>;
|
|
9
9
|
quotationModule?: QuotationModule;
|
|
10
|
+
channel?: string;
|
|
10
11
|
resolveConfig?: (date: string) => VenueBookingSlotConfig;
|
|
11
12
|
}): VenueDateSummaryItem[];
|
|
@@ -15,6 +15,7 @@ function buildDateRangeSummary(params) {
|
|
|
15
15
|
rawResources,
|
|
16
16
|
resourceProductMap,
|
|
17
17
|
quotationModule,
|
|
18
|
+
channel,
|
|
18
19
|
resolveConfig
|
|
19
20
|
} = params;
|
|
20
21
|
const result = [];
|
|
@@ -30,7 +31,8 @@ function buildDateRangeSummary(params) {
|
|
|
30
31
|
const timePoints = timeLabels.map(label => `${date} ${label}`);
|
|
31
32
|
quotationPriceMap = quotationModule.buildProductPriceMap({
|
|
32
33
|
productIds,
|
|
33
|
-
timePoints
|
|
34
|
+
timePoints,
|
|
35
|
+
channel
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
const grid = (0, _timeSlot.buildTimeSlotGrid)({
|
|
@@ -5,10 +5,12 @@ export declare function mergeConsecutiveSlots(slots: VenueSlotSelection[]): Merg
|
|
|
5
5
|
export declare function buildPriceBreakdown(params: {
|
|
6
6
|
group: MergedSlotGroup;
|
|
7
7
|
productId: number;
|
|
8
|
+
channel?: string;
|
|
8
9
|
quotation?: {
|
|
9
10
|
getQuotationShelfId: (p: {
|
|
10
11
|
productId: number;
|
|
11
12
|
datetime: string;
|
|
13
|
+
channel?: string;
|
|
12
14
|
}) => number;
|
|
13
15
|
};
|
|
14
16
|
}): PriceBreakdownEntry[];
|
|
@@ -57,6 +57,7 @@ function buildPriceBreakdown(params) {
|
|
|
57
57
|
const {
|
|
58
58
|
group,
|
|
59
59
|
productId,
|
|
60
|
+
channel,
|
|
60
61
|
quotation
|
|
61
62
|
} = params;
|
|
62
63
|
if (!group.slots.length) return [];
|
|
@@ -65,7 +66,8 @@ function buildPriceBreakdown(params) {
|
|
|
65
66
|
const unitPrice = Number(slot.price || '0');
|
|
66
67
|
const shelfId = quotation ? quotation.getQuotationShelfId({
|
|
67
68
|
productId,
|
|
68
|
-
datetime: slot.startTime
|
|
69
|
+
datetime: slot.startTime,
|
|
70
|
+
channel
|
|
69
71
|
}) : 0;
|
|
70
72
|
const startHm = (0, _dayjs.default)(slot.startTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|
|
71
73
|
const endHm = (0, _dayjs.default)(slot.endTime, 'YYYY-MM-DD HH:mm').format('YYYY-MM-DD HH:mm');
|