@pisell/pisellos 2.1.166 → 2.1.168
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 +0 -1
- package/dist/index.js +0 -3
- package/dist/model/strategy/adapter/index.d.ts +0 -4
- package/dist/model/strategy/adapter/index.js +1 -5
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/modules/Cart/utils/changePrice.js +16 -9
- package/dist/modules/Discount/index.d.ts +2 -5
- package/dist/modules/Discount/index.js +1 -21
- package/dist/modules/Discount/types.d.ts +0 -4
- package/dist/modules/Order/index.d.ts +0 -1
- package/dist/modules/Order/index.js +6 -18
- package/dist/modules/Order/types.d.ts +0 -2
- package/dist/modules/ProductList/index.d.ts +1 -3
- package/dist/modules/ProductList/index.js +11 -22
- package/dist/modules/Schedule/getDateIsInSchedule.js +0 -5
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/ScanOrder/index.js +1 -1
- package/dist/solution/ShopDiscount/index.js +15 -16
- package/dist/solution/VenueBooking/index.d.ts +3 -40
- package/dist/solution/VenueBooking/index.js +261 -394
- package/dist/solution/VenueBooking/types.d.ts +1 -3
- package/dist/solution/VenueBooking/types.js +0 -1
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +9 -3
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -3
- package/lib/model/strategy/adapter/index.d.ts +0 -4
- package/lib/model/strategy/adapter/index.js +2 -13
- package/lib/model/strategy/adapter/promotion/index.js +0 -49
- package/lib/modules/Cart/utils/changePrice.js +13 -9
- package/lib/modules/Discount/index.d.ts +2 -5
- package/lib/modules/Discount/index.js +1 -11
- package/lib/modules/Discount/types.d.ts +0 -4
- package/lib/modules/Order/index.d.ts +0 -1
- package/lib/modules/Order/index.js +1 -11
- package/lib/modules/Order/types.d.ts +0 -2
- package/lib/modules/ProductList/index.d.ts +1 -3
- package/lib/modules/ProductList/index.js +39 -45
- package/lib/modules/Schedule/getDateIsInSchedule.js +0 -4
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/ScanOrder/index.js +1 -1
- package/lib/solution/ShopDiscount/index.js +2 -3
- package/lib/solution/VenueBooking/index.d.ts +3 -40
- package/lib/solution/VenueBooking/index.js +111 -257
- package/lib/solution/VenueBooking/types.d.ts +1 -3
- package/lib/solution/VenueBooking/types.js +0 -1
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +10 -5
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +6 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +4 -3
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/lib/solution/VenueBooking/utils/timeSlot.js +3 -7
- package/package.json +1 -1
- package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
- package/dist/model/strategy/adapter/dataVariant/adapter.js +0 -167
- package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +0 -780
- package/dist/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
- package/dist/model/strategy/adapter/dataVariant/examples.js +0 -277
- package/dist/model/strategy/adapter/dataVariant/index.d.ts +0 -4
- package/dist/model/strategy/adapter/dataVariant/index.js +0 -4
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -148
- package/dist/model/strategy/adapter/dataVariant/type.js +0 -54
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
- package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
- package/lib/model/strategy/adapter/dataVariant/adapter.js +0 -149
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +0 -583
- package/lib/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
- package/lib/model/strategy/adapter/dataVariant/examples.js +0 -293
- package/lib/model/strategy/adapter/dataVariant/index.d.ts +0 -4
- package/lib/model/strategy/adapter/dataVariant/index.js +0 -38
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -148
- package/lib/model/strategy/adapter/dataVariant/type.js +0 -31
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -180
|
@@ -50,7 +50,6 @@ var import_resource = require("./utils/resource");
|
|
|
50
50
|
var import_timeSlot = require("./utils/timeSlot");
|
|
51
51
|
var import_dateSummary = require("./utils/dateSummary");
|
|
52
52
|
var import_slotMerge = require("./utils/slotMerge");
|
|
53
|
-
var import_smartPricing = require("./utils/smartPricing");
|
|
54
53
|
var import_utils3 = require("../../modules/Order/utils");
|
|
55
54
|
var import_Order = require("../../modules/Order");
|
|
56
55
|
var import_types4 = require("../RegisterAndLogin/types");
|
|
@@ -111,10 +110,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
111
110
|
this.loadAllProductsInFlight = null;
|
|
112
111
|
this.productsLoaded = false;
|
|
113
112
|
this.loadOpenDataConfigInFlight = null;
|
|
114
|
-
/** 按日期缓存 slot 智能定价 Map,避免同周重复 resolveProducts */
|
|
115
|
-
this.slotPriceMapCache = /* @__PURE__ */ new Map();
|
|
116
|
-
/** loadProducts 后缓存的全量商品(venue + addon),供分段算价复用 */
|
|
117
|
-
this.smartPricingProductCatalog = [];
|
|
118
113
|
}
|
|
119
114
|
getLoggerContext() {
|
|
120
115
|
return {
|
|
@@ -277,16 +272,19 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
277
272
|
});
|
|
278
273
|
}
|
|
279
274
|
registerCustomerLoginListeners() {
|
|
275
|
+
var _a, _b, _c, _d;
|
|
280
276
|
this.clearLoginEffectListeners();
|
|
281
|
-
const
|
|
277
|
+
const accountModule = (_a = this.core) == null ? void 0 : _a.getModule("account");
|
|
278
|
+
const registerAndLoginModule = (_b = this.core) == null ? void 0 : _b.getModule("registerAndLogin");
|
|
279
|
+
const currentAccount = ((_c = accountModule == null ? void 0 : accountModule.getCurrentAccount) == null ? void 0 : _c.call(accountModule)) || ((_d = accountModule == null ? void 0 : accountModule.getAccount) == null ? void 0 : _d.call(accountModule)) || null;
|
|
280
|
+
const createHandleLogin = (eventName) => async (payload) => {
|
|
282
281
|
const customerId = this.resolveCustomerIdFromLoginPayload(payload);
|
|
283
282
|
if (!customerId)
|
|
284
283
|
return;
|
|
285
284
|
await this.refreshOrderMarketingAfterLogin({ customerId });
|
|
286
285
|
};
|
|
287
|
-
this.registerLoginEffect(
|
|
288
|
-
this.registerLoginEffect(
|
|
289
|
-
this.registerLoginEffect(import_types4.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin());
|
|
286
|
+
this.registerLoginEffect(import_types3.AccountHooks.OnLogin, createHandleLogin(import_types3.AccountHooks.OnLogin));
|
|
287
|
+
this.registerLoginEffect(import_types4.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin(import_types4.RegisterAndLoginHooks.onLoginSuccess));
|
|
290
288
|
}
|
|
291
289
|
async refreshOrderMarketingAfterLogin(params) {
|
|
292
290
|
if (!this.store.order)
|
|
@@ -300,24 +298,20 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
300
298
|
}
|
|
301
299
|
this.customerLoginRefreshIdInFlight = params.customerId;
|
|
302
300
|
const refreshTask = (async () => {
|
|
303
|
-
var _a
|
|
304
|
-
this.
|
|
301
|
+
var _a;
|
|
302
|
+
if (this.store.quotation) {
|
|
303
|
+
await this.store.quotation.loadQuotations({
|
|
304
|
+
channel: (_a = this.otherParams) == null ? void 0 : _a.channel
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
this.recalculateOrderPricesFromQuotation();
|
|
305
308
|
await this.store.order.loadDiscountConfig({
|
|
306
309
|
customerId: params.customerId
|
|
307
310
|
});
|
|
308
|
-
this.clearSlotPriceMapCache();
|
|
309
|
-
this.recalculateOrderPricesFromSmartPricing();
|
|
310
|
-
this.store.order.applyDiscount();
|
|
311
|
-
this.normalizeDiscountedOrderPrices(
|
|
312
|
-
this.store.order.getDiscountList()
|
|
313
|
-
);
|
|
314
311
|
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
315
312
|
this.store.order.persistTempOrder();
|
|
316
313
|
await this.refreshItemRuleQuantityLimits();
|
|
317
314
|
await this.refreshCartValidationPassed();
|
|
318
|
-
await ((_c = (_b = (_a = this.core) == null ? void 0 : _a.effects) == null ? void 0 : _b.emit) == null ? void 0 : _c.call(_b, import_types.VenueBookingHooks.onSmartPricingUpdated, {
|
|
319
|
-
customerId: params.customerId
|
|
320
|
-
}));
|
|
321
315
|
})();
|
|
322
316
|
this.customerLoginRefreshInFlight = refreshTask;
|
|
323
317
|
try {
|
|
@@ -332,12 +326,11 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
332
326
|
}
|
|
333
327
|
}
|
|
334
328
|
async initialize(core, options = {}) {
|
|
335
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
329
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
336
330
|
this.logMethodStart("initialize");
|
|
337
331
|
this.core = core;
|
|
338
332
|
this.initializeOptions = options || {};
|
|
339
333
|
this.store = { ...this.store, ...options.store };
|
|
340
|
-
this.smartPricingCustomerId = void 0;
|
|
341
334
|
this.store.entryContext = ((_a = options.otherParams) == null ? void 0 : _a.entryContext) || this.store.entryContext;
|
|
342
335
|
this.store.status = "initializing";
|
|
343
336
|
this.store.error = null;
|
|
@@ -469,6 +462,10 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
469
462
|
await this.loadRuntimeConfigs();
|
|
470
463
|
if (this.store.schedule) {
|
|
471
464
|
await this.store.schedule.loadAllSchedule();
|
|
465
|
+
this.injectScheduleResolverToQuotation();
|
|
466
|
+
(_k = this.store.quotation) == null ? void 0 : _k.loadQuotations({
|
|
467
|
+
channel: (_j = this.otherParams) == null ? void 0 : _j.channel
|
|
468
|
+
});
|
|
472
469
|
}
|
|
473
470
|
await this.refreshItemRuleQuantityLimits();
|
|
474
471
|
this.store.status = "ready";
|
|
@@ -544,95 +541,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
544
541
|
getCartValidation() {
|
|
545
542
|
return this.store.cartValidation || { passed: null, failures: [] };
|
|
546
543
|
}
|
|
547
|
-
/** 清除 slot 价格分段缓存(商品重载 / 登录后 customerId 变化时调用) */
|
|
548
|
-
clearSlotPriceMapCache() {
|
|
549
|
-
this.slotPriceMapCache.clear();
|
|
550
|
-
}
|
|
551
|
-
/** 读取当前登录 customerId */
|
|
552
|
-
resolveCustomerIdForSmartPricing() {
|
|
553
|
-
var _a, _b, _c;
|
|
554
|
-
if (this.smartPricingCustomerId)
|
|
555
|
-
return this.smartPricingCustomerId;
|
|
556
|
-
try {
|
|
557
|
-
const userPlugin = (_a = this.core) == null ? void 0 : _a.getPlugin("user");
|
|
558
|
-
const customerId = Number((_c = (_b = userPlugin == null ? void 0 : userPlugin.get) == null ? void 0 : _b.call(userPlugin)) == null ? void 0 : _c.id);
|
|
559
|
-
return Number.isFinite(customerId) && customerId > 0 ? customerId : void 0;
|
|
560
|
-
} catch {
|
|
561
|
-
return void 0;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
resolveAvailableWalletIdsForSmartPricing() {
|
|
565
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
566
|
-
const orderWalletIds = (_b = (_a = this.store.order) == null ? void 0 : _a.getAvailableWalletIds) == null ? void 0 : _b.call(_a);
|
|
567
|
-
const fallbackWalletIds = ((_c = this.otherParams) == null ? void 0 : _c.available_wallet_ids) || ((_d = this.otherParams) == null ? void 0 : _d.availableWalletIds) || ((_f = (_e = this.otherParams) == null ? void 0 : _e.strategy_context) == null ? void 0 : _f.available_wallet_ids) || ((_h = (_g = this.otherParams) == null ? void 0 : _g.strategy_context) == null ? void 0 : _h.availableWalletIds);
|
|
568
|
-
const source = Array.isArray(orderWalletIds) && orderWalletIds.length ? orderWalletIds : fallbackWalletIds;
|
|
569
|
-
if (!Array.isArray(source))
|
|
570
|
-
return [];
|
|
571
|
-
const ids = source.map((item) => Number(item)).filter((item) => Number.isFinite(item) && item > 0);
|
|
572
|
-
return Array.from(new Set(ids));
|
|
573
|
-
}
|
|
574
|
-
/** 读取 schedule 全量列表,供智能定价 schedule_match 使用 */
|
|
575
|
-
getScheduleListForSmartPricing() {
|
|
576
|
-
var _a;
|
|
577
|
-
const scheduleModule = this.store.schedule;
|
|
578
|
-
const list = (_a = scheduleModule == null ? void 0 : scheduleModule.store) == null ? void 0 : _a.scheduleList;
|
|
579
|
-
return Array.isArray(list) ? list : [];
|
|
580
|
-
}
|
|
581
|
-
/** 构建智能定价上下文,对齐 OS Server buildProductFormatterContext */
|
|
582
|
-
buildSmartPricingContext(customerId) {
|
|
583
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
584
|
-
const evaluator = (_b = (_a = this.core) == null ? void 0 : _a.context) == null ? void 0 : _b.dataVariantEvaluator;
|
|
585
|
-
return {
|
|
586
|
-
evaluator,
|
|
587
|
-
scheduleList: this.getScheduleListForSmartPricing(),
|
|
588
|
-
menuList: ((_c = this.otherParams) == null ? void 0 : _c.menuList) || ((_e = (_d = this.otherParams) == null ? void 0 : _d.openData) == null ? void 0 : _e.menuList) || [],
|
|
589
|
-
customerId: customerId ?? this.resolveCustomerIdForSmartPricing(),
|
|
590
|
-
availableWalletIds: this.resolveAvailableWalletIdsForSmartPricing(),
|
|
591
|
-
channel: (_f = this.otherParams) == null ? void 0 : _f.channel,
|
|
592
|
-
businessCode: (_g = this.otherParams) == null ? void 0 : _g.businessCode,
|
|
593
|
-
orderType: ((_h = this.otherParams) == null ? void 0 : _h.orderType) || ((_i = this.otherParams) == null ? void 0 : _i.type),
|
|
594
|
-
strategy_context: (_j = this.otherParams) == null ? void 0 : _j.strategy_context
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
/** venue + addon 全量商品,供智能定价评估 */
|
|
598
|
-
getAllProductsForSmartPricing() {
|
|
599
|
-
if (this.smartPricingProductCatalog.length) {
|
|
600
|
-
return this.smartPricingProductCatalog;
|
|
601
|
-
}
|
|
602
|
-
const venueList = this.getVenueProducts();
|
|
603
|
-
const addonList = this.getAddonProductsList();
|
|
604
|
-
return [...venueList, ...addonList];
|
|
605
|
-
}
|
|
606
|
-
getSlotPriceMapCacheKey(date, context) {
|
|
607
|
-
return [
|
|
608
|
-
date,
|
|
609
|
-
context.customerId ?? "",
|
|
610
|
-
(context.availableWalletIds || []).join(","),
|
|
611
|
-
context.channel ?? "",
|
|
612
|
-
context.businessCode ?? ""
|
|
613
|
-
].join("|");
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* 按 schedule 分段构建 slot 价格 Map,带实例级缓存。
|
|
617
|
-
*/
|
|
618
|
-
buildSlotPriceMapForDate(date, config, productIds) {
|
|
619
|
-
const context = this.buildSmartPricingContext();
|
|
620
|
-
const cacheKey = this.getSlotPriceMapCacheKey(date, context);
|
|
621
|
-
const cached = this.slotPriceMapCache.get(cacheKey);
|
|
622
|
-
if (cached)
|
|
623
|
-
return cached;
|
|
624
|
-
const timeLabels = (0, import_timeSlot.generateTimeLabels)(config);
|
|
625
|
-
const slotPriceMap = (0, import_smartPricing.buildSlotPriceMapByScheduleSegments)({
|
|
626
|
-
products: this.getAllProductsForSmartPricing(),
|
|
627
|
-
productIds,
|
|
628
|
-
date,
|
|
629
|
-
timeLabels,
|
|
630
|
-
config,
|
|
631
|
-
context
|
|
632
|
-
});
|
|
633
|
-
this.slotPriceMapCache.set(cacheKey, slotPriceMap);
|
|
634
|
-
return slotPriceMap;
|
|
635
|
-
}
|
|
636
544
|
// ─── 场地商品 & 附加商品 ───
|
|
637
545
|
async loadAllProducts() {
|
|
638
546
|
if (this.loadAllProductsInFlight)
|
|
@@ -661,18 +569,9 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
661
569
|
menu_list_ids: menuListIds,
|
|
662
570
|
cacheId: this.cacheId,
|
|
663
571
|
schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
|
|
664
|
-
schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
665
|
-
with_extra: ["dataVariants"]
|
|
572
|
+
schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
666
573
|
});
|
|
667
|
-
const
|
|
668
|
-
let list = rawList;
|
|
669
|
-
this.smartPricingProductCatalog = rawList.slice();
|
|
670
|
-
list = (0, import_smartPricing.formatProductsWithDataVariant)(
|
|
671
|
-
list,
|
|
672
|
-
this.buildSmartPricingContext(),
|
|
673
|
-
(0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
674
|
-
);
|
|
675
|
-
this.clearSlotPriceMapCache();
|
|
574
|
+
const list = Array.isArray(allProducts) ? allProducts : [];
|
|
676
575
|
const venueList = list.filter((p) => p.duration != null);
|
|
677
576
|
const addonList = list.filter((p) => p.duration == null);
|
|
678
577
|
const venueStore = (_c = this.store.venueProducts) == null ? void 0 : _c.store;
|
|
@@ -853,24 +752,29 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
853
752
|
config: this.baseSlotConfig,
|
|
854
753
|
rawResources: this.store.rawResourceData,
|
|
855
754
|
resourceProductMap: this.resourceProductMap,
|
|
856
|
-
|
|
857
|
-
|
|
755
|
+
quotationModule: this.store.quotation,
|
|
756
|
+
resolveConfig: (date) => this.resolveSlotConfigForDate(date)
|
|
858
757
|
});
|
|
859
758
|
}
|
|
860
759
|
getTimeSlotGrid(date) {
|
|
861
760
|
const resolvedSlotConfig = this.syncOperatingHoursToSlotConfig(date);
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
761
|
+
let quotationPriceMap;
|
|
762
|
+
if (this.store.quotation) {
|
|
763
|
+
const productIds = [
|
|
764
|
+
...new Set(
|
|
765
|
+
[...this.resourceProductMap.values()].flat().map((m) => m.productId)
|
|
766
|
+
)
|
|
767
|
+
];
|
|
768
|
+
const timeLabels = (0, import_timeSlot.generateTimeLabels)(resolvedSlotConfig);
|
|
769
|
+
const timePoints = timeLabels.map((label) => `${date} ${label}`);
|
|
770
|
+
quotationPriceMap = this.store.quotation.buildProductPriceMap({ productIds, timePoints });
|
|
771
|
+
}
|
|
868
772
|
return (0, import_timeSlot.buildTimeSlotGrid)({
|
|
869
773
|
date,
|
|
870
774
|
config: resolvedSlotConfig,
|
|
871
775
|
rawResources: this.store.rawResourceData,
|
|
872
776
|
resourceProductMap: this.resourceProductMap,
|
|
873
|
-
|
|
777
|
+
quotationPriceMap
|
|
874
778
|
});
|
|
875
779
|
}
|
|
876
780
|
// ─── 时间槽订单操作 ───
|
|
@@ -1155,7 +1059,8 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1155
1059
|
booking_uid: bookingUuid,
|
|
1156
1060
|
price_breakdown: (0, import_slotMerge.buildPriceBreakdown)({
|
|
1157
1061
|
group,
|
|
1158
|
-
productId: mapping.productId
|
|
1062
|
+
productId: mapping.productId,
|
|
1063
|
+
quotation: this.store.quotation
|
|
1159
1064
|
})
|
|
1160
1065
|
},
|
|
1161
1066
|
_origin: {
|
|
@@ -1248,12 +1153,20 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1248
1153
|
if (!this.store.schedule)
|
|
1249
1154
|
throw new Error("schedule 模块未初始化");
|
|
1250
1155
|
await this.store.schedule.loadAllSchedule();
|
|
1156
|
+
this.injectScheduleResolverToQuotation();
|
|
1251
1157
|
this.logMethodSuccess("loadSchedules");
|
|
1252
1158
|
} catch (error) {
|
|
1253
1159
|
this.logMethodError("loadSchedules", error);
|
|
1254
1160
|
throw error;
|
|
1255
1161
|
}
|
|
1256
1162
|
}
|
|
1163
|
+
injectScheduleResolverToQuotation() {
|
|
1164
|
+
if (this.store.quotation && this.store.schedule) {
|
|
1165
|
+
this.store.quotation.setScheduleResolver(
|
|
1166
|
+
(id) => this.store.schedule.getScheduleListByIds([id])[0]
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1257
1170
|
getScheduleListByIds(ids) {
|
|
1258
1171
|
if (!this.store.schedule)
|
|
1259
1172
|
return [];
|
|
@@ -1292,16 +1205,14 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1292
1205
|
throw error;
|
|
1293
1206
|
}
|
|
1294
1207
|
}
|
|
1295
|
-
|
|
1208
|
+
recalculateOrderPricesFromQuotation() {
|
|
1296
1209
|
var _a, _b;
|
|
1297
|
-
if (!this.store.order)
|
|
1210
|
+
if (!this.store.order || !this.store.quotation)
|
|
1298
1211
|
return;
|
|
1299
1212
|
const tempOrder = this.store.order.getTempOrder();
|
|
1300
1213
|
if (!((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length))
|
|
1301
1214
|
return;
|
|
1302
1215
|
const now = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1303
|
-
const catalog = this.getAllProductsForSmartPricing();
|
|
1304
|
-
const context = this.buildSmartPricingContext();
|
|
1305
1216
|
for (const product of tempOrder.products) {
|
|
1306
1217
|
if ((_b = product.metadata) == null ? void 0 : _b.venue_booking) {
|
|
1307
1218
|
const mappings = this.resourceProductMap.get(product.metadata.resource_id);
|
|
@@ -1314,75 +1225,37 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1314
1225
|
product,
|
|
1315
1226
|
this.store.slotConfig.slotDurationMinutes
|
|
1316
1227
|
);
|
|
1317
|
-
const
|
|
1318
|
-
...
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
for (const slotDate of uniqueDates) {
|
|
1322
|
-
slotPriceMaps.set(
|
|
1323
|
-
slotDate,
|
|
1324
|
-
this.buildSlotPriceMapForDate(slotDate, this.store.slotConfig, [mapping.productId])
|
|
1325
|
-
);
|
|
1326
|
-
}
|
|
1327
|
-
const updatedSlots = slots.map((slot) => {
|
|
1328
|
-
const slotDate = (0, import_dayjs.default)(slot.startTime).format("YYYY-MM-DD");
|
|
1329
|
-
const slotPriceMap = slotPriceMaps.get(slotDate);
|
|
1330
|
-
return {
|
|
1331
|
-
...slot,
|
|
1228
|
+
const updatedSlots = slots.map((slot) => ({
|
|
1229
|
+
...slot,
|
|
1230
|
+
productId: mapping.productId,
|
|
1231
|
+
price: this.store.quotation.getPriceForProduct({
|
|
1332
1232
|
productId: mapping.productId,
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
slotStartTime: slot.startTime,
|
|
1337
|
-
fallbackPrice: mapping.price
|
|
1338
|
-
}) : mapping.price
|
|
1339
|
-
};
|
|
1340
|
-
});
|
|
1233
|
+
datetime: slot.startTime
|
|
1234
|
+
}) ?? mapping.price
|
|
1235
|
+
}));
|
|
1341
1236
|
const merged = (0, import_slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
1342
1237
|
if (merged.length === 1) {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
})
|
|
1238
|
+
product.selling_price = merged[0].totalPrice;
|
|
1239
|
+
product.original_price = merged[0].totalPrice;
|
|
1240
|
+
product.metadata.price_breakdown = (0, import_slotMerge.buildPriceBreakdown)({
|
|
1241
|
+
group: merged[0],
|
|
1242
|
+
productId: mapping.productId,
|
|
1243
|
+
quotation: this.store.quotation
|
|
1350
1244
|
});
|
|
1351
1245
|
}
|
|
1352
1246
|
} else if (product.product_id != null) {
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
datetime: now,
|
|
1358
|
-
fallbackPrice: product.selling_price
|
|
1359
|
-
});
|
|
1360
|
-
this.resetProductPriceForSmartPricing({
|
|
1361
|
-
product,
|
|
1362
|
-
price: smartPrice
|
|
1247
|
+
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1248
|
+
productId: product.product_id,
|
|
1249
|
+
variantId: product.product_variant_id ?? void 0,
|
|
1250
|
+
datetime: now
|
|
1363
1251
|
});
|
|
1252
|
+
if (quotationPrice !== null) {
|
|
1253
|
+
product.selling_price = quotationPrice;
|
|
1254
|
+
product.original_price = quotationPrice;
|
|
1255
|
+
}
|
|
1364
1256
|
}
|
|
1365
1257
|
}
|
|
1366
1258
|
}
|
|
1367
|
-
/**
|
|
1368
|
-
* DataVariant 重算价格后,同步刷新订单展示、Rules 与 Summary 共用的价格口径。
|
|
1369
|
-
* Rules 会在本轮结束后根据当前客户的 discountList 重新写入实际折扣。
|
|
1370
|
-
*/
|
|
1371
|
-
resetProductPriceForSmartPricing(params) {
|
|
1372
|
-
const { product, price, priceBreakdown } = params;
|
|
1373
|
-
const metadata = product.metadata || {};
|
|
1374
|
-
product.selling_price = price;
|
|
1375
|
-
product.original_price = price;
|
|
1376
|
-
product.discount_list = [];
|
|
1377
|
-
product.metadata = {
|
|
1378
|
-
...metadata,
|
|
1379
|
-
...priceBreakdown ? { price_breakdown: priceBreakdown } : {},
|
|
1380
|
-
source_product_price: price,
|
|
1381
|
-
main_product_original_price: price,
|
|
1382
|
-
main_product_selling_price: price,
|
|
1383
|
-
price_schema_version: 2
|
|
1384
|
-
};
|
|
1385
|
-
}
|
|
1386
1259
|
async scanCode(code, customerId) {
|
|
1387
1260
|
this.logMethodStart("scanCode", { code });
|
|
1388
1261
|
try {
|
|
@@ -1408,7 +1281,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1408
1281
|
}
|
|
1409
1282
|
/** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
|
|
1410
1283
|
async setDiscountSelected(params) {
|
|
1411
|
-
var _a, _b, _c, _d, _e;
|
|
1284
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1412
1285
|
this.logMethodStart("setDiscountSelected", params);
|
|
1413
1286
|
try {
|
|
1414
1287
|
if (!this.store.order)
|
|
@@ -1460,15 +1333,42 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1460
1333
|
}
|
|
1461
1334
|
}
|
|
1462
1335
|
}
|
|
1463
|
-
|
|
1336
|
+
const selectedResourceIds = new Set(
|
|
1337
|
+
nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
|
|
1338
|
+
);
|
|
1339
|
+
for (const product of tempOrder.products) {
|
|
1340
|
+
if ((_c = product._origin) == null ? void 0 : _c.isManualDiscount)
|
|
1341
|
+
continue;
|
|
1342
|
+
product.discount_list = (product.discount_list || []).filter((pd) => {
|
|
1343
|
+
var _a2;
|
|
1344
|
+
const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
|
|
1345
|
+
return rid != null && selectedResourceIds.has(rid);
|
|
1346
|
+
});
|
|
1347
|
+
const totalPerUnitDiscount = (product.discount_list || []).reduce(
|
|
1348
|
+
(sum, pd) => sum + (pd.amount || 0),
|
|
1349
|
+
0
|
|
1350
|
+
);
|
|
1351
|
+
const optionSum = (0, import_utils3.sumOptionUnitPrice)(product.product_option_item);
|
|
1352
|
+
const sourcePrice = ((_d = product.metadata) == null ? void 0 : _d.source_product_price) ?? (((_e = product.metadata) == null ? void 0 : _e.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
|
|
1353
|
+
const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
|
|
1354
|
+
const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
1355
|
+
if (product.metadata) {
|
|
1356
|
+
product.metadata.main_product_selling_price = newMainSellingPrice;
|
|
1357
|
+
product.metadata.price_schema_version = 2;
|
|
1358
|
+
}
|
|
1359
|
+
product.selling_price = (0, import_utils3.composeLinePrice)({
|
|
1360
|
+
mainPrice: newMainSellingPrice,
|
|
1361
|
+
bundle: product.product_bundle
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1464
1364
|
import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
|
|
1465
1365
|
await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
|
|
1466
1366
|
tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
|
|
1467
1367
|
const afterApplyTarget = this.store.order.getDiscountList().find((d) => d.id === params.discountId) || null;
|
|
1468
1368
|
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1469
1369
|
this.store.order.persistTempOrder();
|
|
1470
|
-
const finalSummary = ((
|
|
1471
|
-
const finalProduct = ((
|
|
1370
|
+
const finalSummary = ((_f = this.store.order.getTempOrder()) == null ? void 0 : _f.summary) || null;
|
|
1371
|
+
const finalProduct = ((_h = (_g = this.store.order.getTempOrder()) == null ? void 0 : _g.products) == null ? void 0 : _h[0]) || null;
|
|
1472
1372
|
this.logMethodSuccess("setDiscountSelected", params);
|
|
1473
1373
|
const finalTarget = this.store.order.getDiscountList().find((d) => d.id === params.discountId) || null;
|
|
1474
1374
|
return this.store.order.getDiscountList();
|
|
@@ -1477,51 +1377,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1477
1377
|
throw error;
|
|
1478
1378
|
}
|
|
1479
1379
|
}
|
|
1480
|
-
/**
|
|
1481
|
-
* 统一 VenueBooking 折扣后的订单行价。
|
|
1482
|
-
*
|
|
1483
|
-
* Rules 的 `discount_list.amount` 是已经按适用规则计算出的每件优惠额;它是这里唯一
|
|
1484
|
-
* 的折扣金额来源。使用智能定价写入的 source_product_price 减去该金额,再同步
|
|
1485
|
-
* selling_price 与 Summary 使用的 main_product_selling_price,避免 UI 的购物车行价、
|
|
1486
|
-
* 小计和提交订单各自读取到不同的价格字段。
|
|
1487
|
-
*/
|
|
1488
|
-
normalizeDiscountedOrderPrices(discountList) {
|
|
1489
|
-
var _a;
|
|
1490
|
-
const order = this.store.order;
|
|
1491
|
-
if (!order)
|
|
1492
|
-
return;
|
|
1493
|
-
const tempOrder = order.ensureTempOrder();
|
|
1494
|
-
const selectedResourceIds = new Set(
|
|
1495
|
-
(discountList || []).filter((discount) => discount.isSelected).map((discount) => discount.id)
|
|
1496
|
-
);
|
|
1497
|
-
for (const product of tempOrder.products) {
|
|
1498
|
-
if ((_a = product._origin) == null ? void 0 : _a.isManualDiscount)
|
|
1499
|
-
continue;
|
|
1500
|
-
product.discount_list = (product.discount_list || []).filter((detail) => {
|
|
1501
|
-
var _a2;
|
|
1502
|
-
const resourceId = ((_a2 = detail.discount) == null ? void 0 : _a2.resource_id) ?? detail.id;
|
|
1503
|
-
return resourceId != null && selectedResourceIds.has(resourceId);
|
|
1504
|
-
});
|
|
1505
|
-
const totalPerUnitDiscount = (product.discount_list || []).reduce(
|
|
1506
|
-
(total, detail) => total.plus(detail.amount || 0),
|
|
1507
|
-
new import_decimal.default(0)
|
|
1508
|
-
);
|
|
1509
|
-
const metadata = product.metadata || (product.metadata = {});
|
|
1510
|
-
const optionSum = (0, import_utils3.sumOptionUnitPrice)(product.product_option_item);
|
|
1511
|
-
const sourcePrice = metadata.source_product_price ?? (metadata.main_product_original_price != null ? new import_decimal.default(Number(metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
|
|
1512
|
-
const nextSourceSellingPrice = import_decimal.default.max(
|
|
1513
|
-
0,
|
|
1514
|
-
new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount)
|
|
1515
|
-
).toDecimalPlaces(2).toString();
|
|
1516
|
-
const nextMainSellingPrice = new import_decimal.default(Number(nextSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
1517
|
-
metadata.main_product_selling_price = nextMainSellingPrice;
|
|
1518
|
-
metadata.price_schema_version = 2;
|
|
1519
|
-
product.selling_price = (0, import_utils3.composeLinePrice)({
|
|
1520
|
-
mainPrice: nextMainSellingPrice,
|
|
1521
|
-
bundle: product.product_bundle
|
|
1522
|
-
});
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
1380
|
async addNewOrder() {
|
|
1526
1381
|
this.logMethodStart("addNewOrder");
|
|
1527
1382
|
try {
|
|
@@ -1601,7 +1456,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1601
1456
|
}
|
|
1602
1457
|
}
|
|
1603
1458
|
async addProductToOrder(product) {
|
|
1604
|
-
var _a
|
|
1459
|
+
var _a;
|
|
1605
1460
|
this.logMethodStart("addProductToOrder", {
|
|
1606
1461
|
product_id: product.product_id,
|
|
1607
1462
|
product_variant_id: product.product_variant_id
|
|
@@ -1609,18 +1464,18 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1609
1464
|
try {
|
|
1610
1465
|
if (!this.store.order)
|
|
1611
1466
|
throw new Error("order 模块未初始化");
|
|
1612
|
-
if (!((_a = product.metadata) == null ? void 0 : _a.venue_booking) && product.product_id != null) {
|
|
1613
|
-
const
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
1618
|
-
fallbackPrice: product.selling_price
|
|
1467
|
+
if (!((_a = product.metadata) == null ? void 0 : _a.venue_booking) && this.store.quotation && product.product_id != null) {
|
|
1468
|
+
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1469
|
+
productId: product.product_id,
|
|
1470
|
+
variantId: product.product_variant_id ?? void 0,
|
|
1471
|
+
datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
1619
1472
|
});
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1473
|
+
if (quotationPrice !== null) {
|
|
1474
|
+
product.selling_price = quotationPrice;
|
|
1475
|
+
product.original_price = quotationPrice;
|
|
1476
|
+
} else if (product.selling_price != null) {
|
|
1477
|
+
product.original_price = product.selling_price;
|
|
1478
|
+
}
|
|
1624
1479
|
}
|
|
1625
1480
|
const products = await this.store.order.addProductToOrder(product);
|
|
1626
1481
|
await this.refreshItemRuleQuantityLimits();
|
|
@@ -2087,7 +1942,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
2087
1942
|
};
|
|
2088
1943
|
var VenueBookingImpl = _VenueBookingImpl;
|
|
2089
1944
|
VenueBookingImpl.OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
|
|
2090
|
-
VenueBookingImpl.PISELL1_LOGIN_SUCCESS = "pisell1.login.success";
|
|
2091
1945
|
// ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
|
|
2092
1946
|
//
|
|
2093
1947
|
// 用于物料层持久化 UI 层面的轻量状态(如当前步骤、登录回跳意图等)。
|
|
@@ -6,9 +6,7 @@ export declare enum VenueBookingHooks {
|
|
|
6
6
|
onDestroy = "venueBooking:onDestroy",
|
|
7
7
|
onRetryInit = "venueBooking:onRetryInit",
|
|
8
8
|
onRefresh = "venueBooking:onRefresh",
|
|
9
|
-
onCartValidationChanged = "venueBooking:onCartValidationChanged"
|
|
10
|
-
/** 登录客户的智能定价、营销配置与订单汇总已完成刷新 */
|
|
11
|
-
onSmartPricingUpdated = "venueBooking:onSmartPricingUpdated"
|
|
9
|
+
onCartValidationChanged = "venueBooking:onCartValidationChanged"
|
|
12
10
|
}
|
|
13
11
|
export type VenueBookingStatus = 'idle' | 'initializing' | 'ready' | 'error';
|
|
14
12
|
export interface VenueBookingEntryContext {
|
|
@@ -29,7 +29,6 @@ var VenueBookingHooks = /* @__PURE__ */ ((VenueBookingHooks2) => {
|
|
|
29
29
|
VenueBookingHooks2["onRetryInit"] = "venueBooking:onRetryInit";
|
|
30
30
|
VenueBookingHooks2["onRefresh"] = "venueBooking:onRefresh";
|
|
31
31
|
VenueBookingHooks2["onCartValidationChanged"] = "venueBooking:onCartValidationChanged";
|
|
32
|
-
VenueBookingHooks2["onSmartPricingUpdated"] = "venueBooking:onSmartPricingUpdated";
|
|
33
32
|
return VenueBookingHooks2;
|
|
34
33
|
})(VenueBookingHooks || {});
|
|
35
34
|
var DEFAULT_SLOT_CONFIG = {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { VenueBookingSlotConfig, VenueResourceRawData, VenueDateSummaryItem, ResourceProductMapping } from '../types';
|
|
2
|
+
import type { QuotationModule } from '../../../modules/Quotation';
|
|
2
3
|
export declare function buildDateRangeSummary(params: {
|
|
3
4
|
startDate: string;
|
|
4
5
|
endDate: string;
|
|
5
6
|
config: VenueBookingSlotConfig;
|
|
6
7
|
rawResources: VenueResourceRawData[];
|
|
7
8
|
resourceProductMap: Map<number | string, ResourceProductMapping[]>;
|
|
9
|
+
quotationModule?: QuotationModule;
|
|
8
10
|
resolveConfig?: (date: string) => VenueBookingSlotConfig;
|
|
9
|
-
/** 按日期构建 slot 智能定价 Map */
|
|
10
|
-
buildSlotPriceMap?: (date: string, config: VenueBookingSlotConfig, productIds: number[]) => Map<string, string | null>;
|
|
11
11
|
}): VenueDateSummaryItem[];
|
|
@@ -41,23 +41,28 @@ function buildDateRangeSummary(params) {
|
|
|
41
41
|
config,
|
|
42
42
|
rawResources,
|
|
43
43
|
resourceProductMap,
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
quotationModule,
|
|
45
|
+
resolveConfig
|
|
46
46
|
} = params;
|
|
47
47
|
const result = [];
|
|
48
|
-
const productIds =
|
|
48
|
+
const productIds = quotationModule ? [...new Set([...resourceProductMap.values()].flat().map((m) => m.productId))] : [];
|
|
49
49
|
let cursor = (0, import_dayjs.default)(startDate);
|
|
50
50
|
const end = (0, import_dayjs.default)(endDate);
|
|
51
51
|
while (!cursor.isAfter(end)) {
|
|
52
52
|
const date = cursor.format("YYYY-MM-DD");
|
|
53
53
|
const effectiveConfig = (resolveConfig == null ? void 0 : resolveConfig(date)) || config;
|
|
54
|
-
|
|
54
|
+
let quotationPriceMap;
|
|
55
|
+
if (quotationModule && productIds.length) {
|
|
56
|
+
const timeLabels = (0, import_timeSlot.generateTimeLabels)(effectiveConfig);
|
|
57
|
+
const timePoints = timeLabels.map((label) => `${date} ${label}`);
|
|
58
|
+
quotationPriceMap = quotationModule.buildProductPriceMap({ productIds, timePoints });
|
|
59
|
+
}
|
|
55
60
|
const grid = (0, import_timeSlot.buildTimeSlotGrid)({
|
|
56
61
|
date,
|
|
57
62
|
config: effectiveConfig,
|
|
58
63
|
rawResources,
|
|
59
64
|
resourceProductMap,
|
|
60
|
-
|
|
65
|
+
quotationPriceMap
|
|
61
66
|
});
|
|
62
67
|
let totalSlots = 0;
|
|
63
68
|
let availableSlots = 0;
|
|
@@ -5,6 +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
|
+
quotation?: {
|
|
9
|
+
getQuotationShelfId: (p: {
|
|
10
|
+
productId: number;
|
|
11
|
+
datetime: string;
|
|
12
|
+
}) => number;
|
|
13
|
+
};
|
|
8
14
|
}): PriceBreakdownEntry[];
|
|
9
15
|
export interface BuildVenueBookingParams {
|
|
10
16
|
group: MergedSlotGroup;
|
|
@@ -82,16 +82,17 @@ function mergeConsecutiveSlots(slots) {
|
|
|
82
82
|
return groups;
|
|
83
83
|
}
|
|
84
84
|
function buildPriceBreakdown(params) {
|
|
85
|
-
const { group } = params;
|
|
85
|
+
const { group, productId, quotation } = params;
|
|
86
86
|
if (!group.slots.length)
|
|
87
87
|
return [];
|
|
88
88
|
const entries = [];
|
|
89
89
|
for (const slot of group.slots) {
|
|
90
90
|
const unitPrice = Number(slot.price || "0");
|
|
91
|
+
const shelfId = quotation ? quotation.getQuotationShelfId({ productId, datetime: slot.startTime }) : 0;
|
|
91
92
|
const startHm = (0, import_dayjs.default)(slot.startTime, "YYYY-MM-DD HH:mm").format("YYYY-MM-DD HH:mm");
|
|
92
93
|
const endHm = (0, import_dayjs.default)(slot.endTime, "YYYY-MM-DD HH:mm").format("YYYY-MM-DD HH:mm");
|
|
93
94
|
const last = entries[entries.length - 1];
|
|
94
|
-
if (last && last.unit_price === unitPrice && last.quotation_shelf_id ===
|
|
95
|
+
if (last && last.unit_price === unitPrice && last.quotation_shelf_id === shelfId && last.end_time === startHm) {
|
|
95
96
|
last.end_time = endHm;
|
|
96
97
|
last.quantity += 1;
|
|
97
98
|
} else {
|
|
@@ -99,7 +100,7 @@ function buildPriceBreakdown(params) {
|
|
|
99
100
|
start_time: startHm,
|
|
100
101
|
end_time: endHm,
|
|
101
102
|
unit_price: unitPrice,
|
|
102
|
-
quotation_shelf_id:
|
|
103
|
+
quotation_shelf_id: shelfId,
|
|
103
104
|
quantity: 1
|
|
104
105
|
});
|
|
105
106
|
}
|