@pisell/pisellos 2.2.183 → 2.2.185

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.
@@ -33,7 +33,7 @@ function normalizeOptionItems(optionItems) {
33
33
  if (!Array.isArray(optionItems)) return [];
34
34
  return optionItems.map(function (optionItem) {
35
35
  var _ref, _optionItem$price, _optionItem$num;
36
- var optionGroupItemId = toNumber(optionItem === null || optionItem === void 0 ? void 0 : optionItem.option_group_item_id);
36
+ var optionGroupItemId = toNumber(optionItem === null || optionItem === void 0 ? void 0 : optionItem.id);
37
37
  var price = (_ref = (_optionItem$price = optionItem === null || optionItem === void 0 ? void 0 : optionItem.price) !== null && _optionItem$price !== void 0 ? _optionItem$price : optionItem === null || optionItem === void 0 ? void 0 : optionItem.add_price) !== null && _ref !== void 0 ? _ref : 0;
38
38
  return {
39
39
  option_group_item_id: optionGroupItemId,
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 6 | 3 | 5 | 4;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -929,6 +929,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
929
929
  return;
930
930
  }
931
931
  var previousCustomerId = (_this$store$order$get3 = this.store.order.getOrderCustomer()) === null || _this$store$order$get3 === void 0 ? void 0 : _this$store$order$get3.customer_id;
932
+ var snapshotBeforeSet = this.store.order.getOrderCustomerSnapshot();
932
933
  var patch = formatOrderCustomerPatch(customer);
933
934
  var customerUnchanged = Number(previousCustomerId || 0) === Number(patch.customer_id || 0);
934
935
  if (!customerUnchanged) {
@@ -936,7 +937,15 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
936
937
  this.hasManualDiscountSelection = false;
937
938
  }
938
939
  this.store.order.setOrderCustomer(patch, customer);
940
+ var snapshotAfterOrderSet = this.store.order.getOrderCustomerSnapshot();
939
941
  if (customerUnchanged) {
942
+ // hydrate 后 customer_id 已存在但 _extend.customerSnapshot 仍为空时,
943
+ // 须通知 SalesSdk 刷新 selected(否则会一直停在 onSalesOrderLoaded 时的 null)。
944
+ var snapshotReplenished = !snapshotBeforeSet && Boolean(snapshotAfterOrderSet);
945
+ if (snapshotReplenished) {
946
+ var _next2 = this.buildOrderCustomerPayload();
947
+ this.core.effects.emit("".concat(this.name, ":onOrderCustomerChange"), _next2);
948
+ }
940
949
  return;
941
950
  }
942
951
  var next = this.buildOrderCustomerPayload();
@@ -528,7 +528,8 @@ var PromotionEvaluator = class {
528
528
  return b.price - a.price;
529
529
  });
530
530
  const totalUnits = unitProducts.length;
531
- const groupCount = cumulative ? Math.floor(totalUnits / x) : totalUnits >= x ? 1 : 0;
531
+ const isCumulative = cumulative !== false;
532
+ const groupCount = isCumulative ? Math.floor(totalUnits / x) : totalUnits >= x ? 1 : 0;
532
533
  const promotionUnits = groupCount * x;
533
534
  const inPromotionUnits = unitProducts.slice(0, promotionUnits);
534
535
  const notInPromotionUnits = unitProducts.slice(promotionUnits);
@@ -264,7 +264,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
264
264
  private logSubmitBackendRejected;
265
265
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
266
266
  createOrder(params: CommitOrderParams['query']): {
267
- type: "virtual" | "appointment_booking";
267
+ type: "appointment_booking" | "virtual";
268
268
  platform: string;
269
269
  sales_channel: string;
270
270
  order_sales_channel: string;
@@ -312,6 +312,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
312
312
  recalcOnHydrate?: boolean;
313
313
  }): Promise<OrderTempOrder>;
314
314
  private normalizeTempOrderForRuntime;
315
+ private normalizeHydratedProductOptionItem;
316
+ private resolveHydratedProductOptions;
315
317
  private normalizeHydratedOrderProduct;
316
318
  getLastOrderInfo(): Record<string, any> | undefined;
317
319
  getOrderInfo(order_id: number): Promise<any>;
@@ -1443,7 +1443,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1443
1443
  productToAdd.product_option_item,
1444
1444
  productToAdd.product_bundle
1445
1445
  );
1446
- const normalizedIncoming = (0, import_utils3.normalizeOrderProduct)(productToAdd);
1446
+ const normalizedIncoming = (0, import_utils.mergeOrderProductDisplayFields)(
1447
+ productToAdd,
1448
+ (0, import_utils3.normalizeOrderProduct)(productToAdd)
1449
+ );
1447
1450
  normalizedIncoming.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1448
1451
  normalizedIncoming.discount_list
1449
1452
  );
@@ -1496,13 +1499,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1496
1499
  } else {
1497
1500
  const targetProduct = matchedProduct;
1498
1501
  const targetUid = (_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number;
1499
- const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
1500
- ...productToAdd,
1501
- metadata: {
1502
- ...productToAdd.metadata || {},
1503
- unique_identification_number: targetUid
1504
- }
1505
- });
1502
+ const normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
1503
+ targetProduct,
1504
+ (0, import_utils3.normalizeOrderProduct)({
1505
+ ...productToAdd,
1506
+ metadata: {
1507
+ ...productToAdd.metadata || {},
1508
+ unique_identification_number: targetUid
1509
+ }
1510
+ })
1511
+ );
1506
1512
  normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1507
1513
  normalizedProduct.discount_list
1508
1514
  );
@@ -1553,7 +1559,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1553
1559
  );
1554
1560
  }
1555
1561
  async updateOrderProduct(params) {
1556
- var _a, _b, _c, _d, _e, _f, _g;
1562
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1557
1563
  const {
1558
1564
  product_id,
1559
1565
  product_variant_id,
@@ -1621,13 +1627,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1621
1627
  delete nextProduct.metadata.main_product_original_price;
1622
1628
  delete nextProduct.metadata.price_schema_version;
1623
1629
  }
1624
- let normalizedProduct = (0, import_utils3.normalizeOrderProduct)(nextProduct);
1630
+ let normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
1631
+ nextProduct,
1632
+ (0, import_utils3.normalizeOrderProduct)(nextProduct)
1633
+ );
1625
1634
  normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1626
1635
  normalizedProduct.discount_list
1627
1636
  );
1637
+ const preservedBookingUid = nextProduct.booking_uid || ((_e = nextProduct.metadata) == null ? void 0 : _e.booking_uid) || targetProduct.booking_uid || ((_f = targetProduct.metadata) == null ? void 0 : _f.booking_uid);
1638
+ if (!booking && preservedBookingUid) {
1639
+ normalizedProduct.booking_uid = preservedBookingUid;
1640
+ normalizedProduct.metadata = {
1641
+ ...normalizedProduct.metadata || {},
1642
+ booking_uid: preservedBookingUid
1643
+ };
1644
+ }
1628
1645
  if (booking) {
1629
1646
  const productUid = String(
1630
- ((_e = normalizedProduct.metadata) == null ? void 0 : _e.unique_identification_number) || ((_f = targetProduct.metadata) == null ? void 0 : _f.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
1647
+ ((_g = normalizedProduct.metadata) == null ? void 0 : _g.unique_identification_number) || ((_h = targetProduct.metadata) == null ? void 0 : _h.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
1631
1648
  );
1632
1649
  normalizedProduct.metadata = {
1633
1650
  ...normalizedProduct.metadata || {},
@@ -1657,7 +1674,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1657
1674
  tempOrder,
1658
1675
  updates,
1659
1676
  tempOrder.products[productIndex],
1660
- (_g = tempOrder.products[productIndex].metadata) == null ? void 0 : _g.unique_identification_number
1677
+ (_i = tempOrder.products[productIndex].metadata) == null ? void 0 : _i.unique_identification_number
1661
1678
  );
1662
1679
  await this.applyPromotion();
1663
1680
  this.applyDiscount();
@@ -2240,7 +2257,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2240
2257
  async getOrderInfoByRemote(order_id) {
2241
2258
  const res = await this.request.get(`/order/sales/${order_id}`, {
2242
2259
  with: ["products", "bookings", "payments", "customer", "summary", "contacts_info"]
2243
- });
2260
+ }, { osServer: true });
2244
2261
  if (res.code === 200) {
2245
2262
  this.store.lastOrderInfo = res.data;
2246
2263
  }
@@ -2305,17 +2322,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2305
2322
  nextTempOrder.vouchers = raw.vouchers || [];
2306
2323
  return nextTempOrder;
2307
2324
  }
2325
+ normalizeHydratedProductOptionItem(optionItem) {
2326
+ const rawNum = (optionItem == null ? void 0 : optionItem.num) ?? (optionItem == null ? void 0 : optionItem.quantity) ?? 1;
2327
+ const parsedNum = Number(rawNum);
2328
+ const rawPrice = (optionItem == null ? void 0 : optionItem.price) ?? (optionItem == null ? void 0 : optionItem.add_price) ?? 0;
2329
+ const parsedPrice = Number(rawPrice);
2330
+ return {
2331
+ option_group_item_id: optionItem == null ? void 0 : optionItem.option_group_item_id,
2332
+ option_group_id: optionItem == null ? void 0 : optionItem.option_group_id,
2333
+ num: Number.isFinite(parsedNum) && parsedNum > 0 ? parsedNum : 1,
2334
+ price: Number.isFinite(parsedPrice) ? parsedPrice : 0
2335
+ };
2336
+ }
2337
+ resolveHydratedProductOptions(row) {
2338
+ var _a;
2339
+ if (Array.isArray(row.product_option_item) && row.product_option_item.length > 0) {
2340
+ return row.product_option_item;
2341
+ }
2342
+ const skuOptions = (_a = row.product_sku) == null ? void 0 : _a.option;
2343
+ if (!Array.isArray(skuOptions))
2344
+ return [];
2345
+ return skuOptions.map(
2346
+ (optionItem) => this.normalizeHydratedProductOptionItem(optionItem || {})
2347
+ );
2348
+ }
2308
2349
  normalizeHydratedOrderProduct(product) {
2309
2350
  const row = { ...product || {} };
2310
2351
  if (row.num === void 0 && row.product_quantity !== void 0) {
2311
2352
  row.num = row.product_quantity;
2312
2353
  }
2313
- if (!Array.isArray(row.product_option_item))
2314
- row.product_option_item = [];
2354
+ row.product_option_item = this.resolveHydratedProductOptions(row);
2315
2355
  if (!Array.isArray(row.product_bundle))
2316
2356
  row.product_bundle = [];
2317
2357
  if (!row.metadata || typeof row.metadata !== "object")
2318
2358
  row.metadata = {};
2359
+ if (row.booking_uid && !row.metadata.booking_uid) {
2360
+ row.metadata.booking_uid = row.booking_uid;
2361
+ }
2319
2362
  const existingIdentity = row.metadata.unique_identification_number || row.unique_identification_number;
2320
2363
  if (!existingIdentity) {
2321
2364
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
@@ -2327,6 +2370,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2327
2370
  const result = {
2328
2371
  ...row,
2329
2372
  ...normalized,
2373
+ product_sku: row.product_sku,
2330
2374
  metadata: {
2331
2375
  ...row.metadata,
2332
2376
  ...normalized.metadata
@@ -397,6 +397,7 @@ export interface SubmitSalesOrderParams {
397
397
  products: OrderSubmitProduct[];
398
398
  bookings: OrderSubmitBooking[];
399
399
  payments: any[];
400
+ vouchers: any[];
400
401
  surcharges?: any[];
401
402
  relation_forms: any[];
402
403
  form_record_ids?: OrderSubmitFormRecord[];
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
49
49
  getCategories(): ProductCategory[];
50
50
  setOtherParams(key: string, value: any): void;
51
51
  getOtherParams(): any;
52
- getProductType(): "duration" | "session" | "normal";
52
+ getProductType(): "normal" | "duration" | "session";
53
53
  }
@@ -430,7 +430,6 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
430
430
  throw new Error("order 模块未初始化");
431
431
  const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
432
432
  const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
433
- debugger;
434
433
  if (!params.forceRemote) {
435
434
  const localRecord = params.orderId !== void 0 ? await this.store.order.getLocalOrderByOrderId(params.orderId) : externalSaleNumber ? await this.store.order.getLocalOrderByExternalSaleNumber(externalSaleNumber) : params.orderNumber ? await this.store.order.getLocalOrderByOrderNumber(params.orderNumber) : null;
436
435
  if (localRecord) {
@@ -176,6 +176,18 @@ export declare function getOrderProductOriginalPriceForPromotion(product: any):
176
176
  export declare function mergeIdenticalPromotionCartLines(products: any[]): any[];
177
177
  /** 获取行 uid(统一以 `metadata.unique_identification_number` 为唯一键) */
178
178
  export declare function getOrderProductUid(product: any): string;
179
+ /**
180
+ * 促销评估前合并同 SKU 拆分行(含促销/原价行),避免加购后仅前 2 件享受优惠。
181
+ * 带 `booking_uid` 的预约行不参与合并(每次加车独立 booking + 商品行)。
182
+ *
183
+ * @example
184
+ * consolidateMainProductsForPromotion([
185
+ * { item: promoLineNum2, originalListIndex: 0 },
186
+ * { item: regularLineNum2, originalListIndex: 1 },
187
+ * ]);
188
+ * // => 单行 num=4,清除 _promotion 后重新评估
189
+ */
190
+ export declare function buildConsolidateKeyForPromotion(item: any): string;
179
191
  /**
180
192
  * 从策略配置的 product_match 规则提取可参与商品列表。
181
193
  *
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var cartPromotion_exports = {};
31
31
  __export(cartPromotion_exports, {
32
32
  appendPromotionTags: () => appendPromotionTags,
33
+ buildConsolidateKeyForPromotion: () => buildConsolidateKeyForPromotion,
33
34
  calculateUnfulfilledPromotions: () => calculateUnfulfilledPromotions,
34
35
  extractProductMatchIdentifiersFromStrategyConfig: () => extractProductMatchIdentifiersFromStrategyConfig,
35
36
  getOrderProductBasePrice: () => getOrderProductBasePrice,
@@ -151,7 +152,7 @@ function resolveXItemsExpectedUnitPrice(promotion, sourceCartNum) {
151
152
  return Number(new import_decimal.default(y).div(x).toDecimalPlaces(2).toFixed(2));
152
153
  }
153
154
  function mergeIdenticalPromotionCartLines(products) {
154
- var _a, _b, _c;
155
+ var _a, _b, _c, _d;
155
156
  if (!Array.isArray(products) || products.length <= 1) {
156
157
  return [...products || []];
157
158
  }
@@ -177,10 +178,12 @@ function mergeIdenticalPromotionCartLines(products) {
177
178
  const promoUnitPrice = String(
178
179
  promotion.finalPrice ?? ((_c = line.metadata) == null ? void 0 : _c.main_product_selling_price) ?? ""
179
180
  );
181
+ const bookingUid = (line == null ? void 0 : line.booking_uid) ?? ((_d = line == null ? void 0 : line.metadata) == null ? void 0 : _d.booking_uid);
180
182
  const mergeKey = [
181
183
  line.product_id,
182
184
  line.product_variant_id ?? 0,
183
185
  fingerprint,
186
+ bookingUid ? String(bookingUid) : "",
184
187
  promotion.strategyId,
185
188
  unitPrice,
186
189
  promoUnitPrice
@@ -197,7 +200,7 @@ function mergeIdenticalPromotionCartLines(products) {
197
200
  return merged;
198
201
  }
199
202
  function dedupePromotionProcessedLines(lines) {
200
- var _a, _b, _c, _d, _e, _f, _g;
203
+ var _a, _b, _c, _d, _e, _f, _g, _h;
201
204
  if (!Array.isArray(lines) || lines.length <= 1)
202
205
  return [...lines || []];
203
206
  const passthrough = [];
@@ -263,9 +266,24 @@ function dedupePromotionProcessedLines(lines) {
263
266
  return promotionDelta(line) > promotionDelta(best) ? line : best;
264
267
  }, pool[0]);
265
268
  }
266
- winner.num = (0, import_utils2.getSafeProductNum)(sourceCartNum || winner.num || 1);
269
+ const winnerIsXItems = getPromotionActionType((_c = winner.metadata) == null ? void 0 : _c._promotion) === X_ITEMS_FOR_Y_PRICE;
270
+ if (winnerIsXItems) {
271
+ const xItemsGroupLines = group.filter(
272
+ (line) => {
273
+ var _a2;
274
+ return getPromotionActionType((_a2 = line.metadata) == null ? void 0 : _a2._promotion) === X_ITEMS_FOR_Y_PRICE;
275
+ }
276
+ );
277
+ const evaluatedPromoQty = xItemsGroupLines.reduce(
278
+ (sum, line) => sum + Number(line.num || 0),
279
+ 0
280
+ );
281
+ winner.num = (0, import_utils2.getSafeProductNum)(evaluatedPromoQty || winner.num || 1);
282
+ } else {
283
+ winner.num = (0, import_utils2.getSafeProductNum)(sourceCartNum || winner.num || 1);
284
+ }
267
285
  const recomputeUnit = resolveXItemsExpectedUnitPrice(
268
- (_c = winner.metadata) == null ? void 0 : _c._promotion,
286
+ (_d = winner.metadata) == null ? void 0 : _d._promotion,
269
287
  sourceCartNum
270
288
  );
271
289
  if (recomputeUnit != null) {
@@ -273,13 +291,13 @@ function dedupePromotionProcessedLines(lines) {
273
291
  applyPromoUnitPriceToLine(winner, {
274
292
  promoUnitPrice: recomputeUnit,
275
293
  originalBasePrice: Number(promo.originalPrice),
276
- strategyTitle: (_d = promo.strategyMetadata) == null ? void 0 : _d.name
294
+ strategyTitle: (_e = promo.strategyMetadata) == null ? void 0 : _e.name
277
295
  });
278
296
  promo.finalPrice = recomputeUnit;
279
297
  }
280
298
  for (const line of group) {
281
- const giftInfo = (_f = (_e = line.metadata) == null ? void 0 : _e._promotion) == null ? void 0 : _f.giftInfo;
282
- if (giftInfo && ((_g = winner.metadata) == null ? void 0 : _g._promotion) && !winner.metadata._promotion.giftInfo) {
299
+ const giftInfo = (_g = (_f = line.metadata) == null ? void 0 : _f._promotion) == null ? void 0 : _g.giftInfo;
300
+ if (giftInfo && ((_h = winner.metadata) == null ? void 0 : _h._promotion) && !winner.metadata._promotion.giftInfo) {
283
301
  winner.metadata._promotion.giftInfo = giftInfo;
284
302
  }
285
303
  }
@@ -309,12 +327,93 @@ function getProductBundleForEvaluator(product) {
309
327
  _bundle_product_id: (b == null ? void 0 : b._bundle_product_id) ?? (b == null ? void 0 : b.bundle_product_id) ?? (b == null ? void 0 : b.product_id)
310
328
  }));
311
329
  }
330
+ function buildConsolidateKeyForPromotion(item) {
331
+ var _a;
332
+ const fingerprint = (0, import_utils2.buildProductLineFingerprint)(
333
+ item.product_option_item,
334
+ item.product_bundle
335
+ );
336
+ const bookingUid = (item == null ? void 0 : item.booking_uid) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.booking_uid);
337
+ if (bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "") {
338
+ return [
339
+ item.product_id,
340
+ item.product_variant_id ?? 0,
341
+ fingerprint,
342
+ String(bookingUid)
343
+ ].join("#");
344
+ }
345
+ return [item.product_id, item.product_variant_id ?? 0, fingerprint].join("#");
346
+ }
347
+ function consolidateMainProductsForPromotion(entries) {
348
+ if (!Array.isArray(entries) || entries.length <= 1) {
349
+ return [...entries || []];
350
+ }
351
+ const groups = /* @__PURE__ */ new Map();
352
+ for (const { item, originalListIndex } of entries) {
353
+ const key = buildConsolidateKeyForPromotion(item);
354
+ const existing = groups.get(key);
355
+ if (!existing) {
356
+ const mergedItem = (0, import_lodash_es.cloneDeep)(item);
357
+ const metadata = mergedItem.metadata || {};
358
+ delete metadata._promotion;
359
+ mergedItem.metadata = metadata;
360
+ if (Array.isArray(mergedItem.product_bundle)) {
361
+ for (const bundle of mergedItem.product_bundle) {
362
+ if (bundle && typeof bundle === "object")
363
+ delete bundle._promotion;
364
+ }
365
+ }
366
+ groups.set(key, { item: mergedItem, originalListIndex });
367
+ continue;
368
+ }
369
+ existing.item.num = (0, import_utils2.getSafeProductNum)(
370
+ Number(existing.item.num || 0) + Number(item.num || 0)
371
+ );
372
+ }
373
+ return Array.from(groups.values());
374
+ }
375
+ function splitXItemsPromoLinesByGroup(lines, strategyActionMap) {
376
+ var _a;
377
+ const result = [];
378
+ for (const line of lines) {
379
+ const promo = (_a = line == null ? void 0 : line.metadata) == null ? void 0 : _a._promotion;
380
+ if (!(promo == null ? void 0 : promo.inPromotion) || !promo.strategyId) {
381
+ result.push(line);
382
+ continue;
383
+ }
384
+ if (getPromotionActionType(promo) !== X_ITEMS_FOR_Y_PRICE) {
385
+ result.push(line);
386
+ continue;
387
+ }
388
+ const actionMeta = strategyActionMap.get(promo.strategyId);
389
+ const detail = (actionMeta == null ? void 0 : actionMeta.actionDetail) ?? promo.actionDetail;
390
+ const x = Number(detail == null ? void 0 : detail.x);
391
+ const num = Number(line.num || 0);
392
+ const isCumulative = (detail == null ? void 0 : detail.cumulative) !== false;
393
+ if (!isCumulative || !Number.isFinite(x) || x <= 0 || num <= x || num % x !== 0) {
394
+ result.push(line);
395
+ continue;
396
+ }
397
+ const groupCount = num / x;
398
+ for (let i = 0; i < groupCount; i++) {
399
+ const splitLine = (0, import_lodash_es.cloneDeep)(line);
400
+ splitLine.num = (0, import_utils2.getSafeProductNum)(x);
401
+ splitLine.metadata = {
402
+ ...splitLine.metadata || {},
403
+ unique_identification_number: (0, import_utils.createUuidV4)()
404
+ };
405
+ result.push(splitLine);
406
+ }
407
+ }
408
+ return result;
409
+ }
312
410
  function generateNumericId() {
313
411
  return Math.floor(Math.random() * 1e9) + Date.now();
314
412
  }
315
413
  function convertToPromotionProduct(product, index) {
316
414
  const metadata = (product == null ? void 0 : product.metadata) || {};
317
415
  const numericId = generateNumericId();
416
+ const originalItem = product;
318
417
  return {
319
418
  id: numericId,
320
419
  product_id: Number((product == null ? void 0 : product.product_id) ?? 0) || 0,
@@ -323,7 +422,7 @@ function convertToPromotionProduct(product, index) {
323
422
  price: getOrderProductOriginalPriceForPromotion(product),
324
423
  quantity: Number((product == null ? void 0 : product.num) ?? 1) || 1,
325
424
  bundle: getProductBundleForEvaluator(product),
326
- _originalItem: product,
425
+ _originalItem: originalItem,
327
426
  _originalId: getOrderProductUid(product),
328
427
  _originalIndex: index
329
428
  };
@@ -548,7 +647,10 @@ function processCartPromotion(list, evaluator, options) {
548
647
  mainProductsWithIndex.push({ item, originalListIndex: i });
549
648
  }
550
649
  }
551
- const mainProducts = mainProductsWithIndex.map((x) => x.item);
650
+ const consolidatedMainProductsWithIndex = consolidateMainProductsForPromotion(
651
+ mainProductsWithIndex
652
+ );
653
+ const mainProducts = consolidatedMainProductsWithIndex.map((x) => x.item);
552
654
  const existingGifts = existingGiftsWithIndex.map((x) => x.item);
553
655
  if (mainProducts.length === 0) {
554
656
  const editProducts = editProductsWithIndex.map((x) => x.item);
@@ -574,7 +676,7 @@ function processCartPromotion(list, evaluator, options) {
574
676
  }
575
677
  const promotionProducts = [];
576
678
  const originalItemMap = /* @__PURE__ */ new Map();
577
- const productsForStrategies = mainProductsWithIndex.map(({ item }, i) => {
679
+ const productsForStrategies = consolidatedMainProductsWithIndex.map(({ item }, i) => {
578
680
  var _a2;
579
681
  return {
580
682
  id: i,
@@ -586,8 +688,8 @@ function processCartPromotion(list, evaluator, options) {
586
688
  bundle: getProductBundleForEvaluator(item)
587
689
  };
588
690
  });
589
- for (let i = 0; i < mainProductsWithIndex.length; i++) {
590
- const { item, originalListIndex } = mainProductsWithIndex[i];
691
+ for (let i = 0; i < consolidatedMainProductsWithIndex.length; i++) {
692
+ const { item, originalListIndex } = consolidatedMainProductsWithIndex[i];
591
693
  const promotionProduct = convertToPromotionProduct(item, originalListIndex);
592
694
  promotionProducts.push(promotionProduct);
593
695
  originalItemMap.set(promotionProduct.id, { item, index: originalListIndex });
@@ -765,6 +867,8 @@ function processCartPromotion(list, evaluator, options) {
765
867
  processedProducts.splice(0, processedProducts.length, ...dedupedPromotionLines);
766
868
  const mergedPromotionLines = mergeIdenticalPromotionCartLines(processedProducts);
767
869
  processedProducts.splice(0, processedProducts.length, ...mergedPromotionLines);
870
+ const splitPromoLines = splitXItemsPromoLinesByGroup(processedProducts, strategyActionMap);
871
+ processedProducts.splice(0, processedProducts.length, ...splitPromoLines);
768
872
  for (const product of processedProducts) {
769
873
  const metadata = product.metadata || {};
770
874
  if (metadata._promotion)
@@ -812,6 +916,7 @@ function processCartPromotion(list, evaluator, options) {
812
916
  delete product._sortIndex;
813
917
  delete product._sortSubIndex;
814
918
  delete product._originalProductUid;
919
+ delete product._sourceCartNum;
815
920
  }
816
921
  return {
817
922
  products: processedProducts,
@@ -824,6 +929,7 @@ function processCartPromotion(list, evaluator, options) {
824
929
  // Annotate the CommonJS export names for ESM import in node:
825
930
  0 && (module.exports = {
826
931
  appendPromotionTags,
932
+ buildConsolidateKeyForPromotion,
827
933
  calculateUnfulfilledPromotions,
828
934
  extractProductMatchIdentifiersFromStrategyConfig,
829
935
  getOrderProductBasePrice,
@@ -53,7 +53,7 @@ function normalizeOptionItems(optionItems) {
53
53
  if (!Array.isArray(optionItems))
54
54
  return [];
55
55
  return optionItems.map((optionItem) => {
56
- const optionGroupItemId = toNumber(optionItem == null ? void 0 : optionItem.option_group_item_id);
56
+ const optionGroupItemId = toNumber(optionItem == null ? void 0 : optionItem.id);
57
57
  const price = (optionItem == null ? void 0 : optionItem.price) ?? (optionItem == null ? void 0 : optionItem.add_price) ?? 0;
58
58
  return {
59
59
  option_group_item_id: optionGroupItemId,
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 6 | 3 | 5 | 4;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -520,6 +520,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
520
520
  return;
521
521
  }
522
522
  const previousCustomerId = (_a = this.store.order.getOrderCustomer()) == null ? void 0 : _a.customer_id;
523
+ const snapshotBeforeSet = this.store.order.getOrderCustomerSnapshot();
523
524
  const patch = (0, import_orderCustomer.formatOrderCustomerPatch)(customer);
524
525
  const customerUnchanged = Number(previousCustomerId || 0) === Number(patch.customer_id || 0);
525
526
  if (!customerUnchanged) {
@@ -527,7 +528,13 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
527
528
  this.hasManualDiscountSelection = false;
528
529
  }
529
530
  this.store.order.setOrderCustomer(patch, customer);
531
+ const snapshotAfterOrderSet = this.store.order.getOrderCustomerSnapshot();
530
532
  if (customerUnchanged) {
533
+ const snapshotReplenished = !snapshotBeforeSet && Boolean(snapshotAfterOrderSet);
534
+ if (snapshotReplenished) {
535
+ const next2 = this.buildOrderCustomerPayload();
536
+ this.core.effects.emit(`${this.name}:onOrderCustomerChange`, next2);
537
+ }
531
538
  return;
532
539
  }
533
540
  const next = this.buildOrderCustomerPayload();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.183",
4
+ "version": "2.2.185",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",