@pisell/pisellos 2.2.172 → 2.2.174

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.
Files changed (34) hide show
  1. package/dist/modules/Order/index.d.ts +6 -21
  2. package/dist/modules/Order/index.js +56 -103
  3. package/dist/modules/Order/types.d.ts +3 -2
  4. package/dist/modules/Order/utils.d.ts +16 -0
  5. package/dist/modules/Order/utils.js +82 -2
  6. package/dist/modules/Quotation/index.d.ts +0 -1
  7. package/dist/modules/Quotation/index.js +8 -17
  8. package/dist/server/modules/products/index.d.ts +1 -1
  9. package/dist/server/modules/products/index.js +128 -112
  10. package/dist/solution/BaseSales/index.d.ts +4 -16
  11. package/dist/solution/BaseSales/index.js +178 -104
  12. package/dist/solution/BaseSales/types.d.ts +14 -0
  13. package/dist/solution/BaseSales/utils/quotationPrice.js +95 -17
  14. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +4 -2
  15. package/dist/solution/BookingByStep/index.d.ts +1 -1
  16. package/dist/solution/BookingTicket/index.js +10 -2
  17. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  18. package/lib/modules/Order/index.d.ts +6 -21
  19. package/lib/modules/Order/index.js +55 -100
  20. package/lib/modules/Order/types.d.ts +3 -2
  21. package/lib/modules/Order/utils.d.ts +16 -0
  22. package/lib/modules/Order/utils.js +54 -2
  23. package/lib/modules/Quotation/index.d.ts +0 -1
  24. package/lib/modules/Quotation/index.js +1 -9
  25. package/lib/server/modules/products/index.d.ts +1 -1
  26. package/lib/server/modules/products/index.js +26 -15
  27. package/lib/solution/BaseSales/index.d.ts +4 -16
  28. package/lib/solution/BaseSales/index.js +71 -35
  29. package/lib/solution/BaseSales/types.d.ts +14 -0
  30. package/lib/solution/BaseSales/utils/quotationPrice.js +90 -14
  31. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -1
  32. package/lib/solution/BookingByStep/index.d.ts +1 -1
  33. package/lib/solution/BookingTicket/index.js +8 -0
  34. package/package.json +1 -1
@@ -31,6 +31,7 @@ var utils_exports = {};
31
31
  __export(utils_exports, {
32
32
  buildManualProductDiscountItem: () => import_manualProductDiscount.buildManualProductDiscountItem,
33
33
  buildSubmitPayload: () => buildSubmitPayload,
34
+ clearTempOrderHolderAssignments: () => clearTempOrderHolderAssignments,
34
35
  composeLinePrice: () => composeLinePrice,
35
36
  createDefaultOrderRulesHooks: () => createDefaultOrderRulesHooks,
36
37
  createDefaultTempOrder: () => createDefaultTempOrder,
@@ -42,6 +43,7 @@ __export(utils_exports, {
42
43
  formatV1Product: () => formatV1Product,
43
44
  generateDuration: () => generateDuration,
44
45
  getAllDiscountList: () => getAllDiscountList,
46
+ hasAssignedHolderId: () => hasAssignedHolderId,
45
47
  isTempOrder: () => isTempOrder,
46
48
  mapPaymentItemToOrderPayment: () => mapPaymentItemToOrderPayment,
47
49
  mapPaymentItemsToOrderPayments: () => mapPaymentItemsToOrderPayments,
@@ -201,7 +203,7 @@ function createDefaultOrderRulesHooks() {
201
203
  id: product.product_id,
202
204
  // Rules 引擎用 _id 作为 processedProductsMap 键;必须与购物车行级 identity 一致,
203
205
  // 否则同 SKU 不同小料会在 calcDiscount 重组时互相覆盖。
204
- // 不透明 identity 契约下,normalizeOrderProduct / restoreTempOrderFromStorage 已保证唯一值存在;
206
+ // 不透明 identity 契约下,normalizeOrderProduct / hydrate 已保证唯一值存在;
205
207
  // 留 fingerprint 分支仅作 Rules 单测里直接传裸 product 时的兜底。
206
208
  _id: ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) ? `${product.product_id}_${product.product_variant_id}_${product.metadata.unique_identification_number}` : `${product.product_id}_${product.product_variant_id}_${(0, import_utils.buildProductLineFingerprint)(
207
209
  product.product_option_item,
@@ -613,7 +615,8 @@ function buildSubmitPayload(params) {
613
615
  }
614
616
  const payload = {
615
617
  ...tempOrderRest,
616
- customer_id: tempOrder.customer_id ?? 0,
618
+ customer_id: tempOrder.customer_id ?? 1,
619
+ customer_name: tempOrder.customer_name || "Select a customer",
617
620
  order_number: null,
618
621
  shop_order_number: null,
619
622
  shop_full_order_number: null,
@@ -720,10 +723,58 @@ function formatV1Product(products) {
720
723
  };
721
724
  });
722
725
  }
726
+ function hasAssignedHolderId(value) {
727
+ if (value === void 0 || value === null || value === "")
728
+ return false;
729
+ if (Array.isArray(value))
730
+ return value.length > 0;
731
+ return true;
732
+ }
733
+ function clearTempOrderHolderAssignments(tempOrder) {
734
+ var _a;
735
+ let changed = false;
736
+ const resetHolderField = (target, key = "holder_id") => {
737
+ if (!hasAssignedHolderId(target[key]))
738
+ return;
739
+ target[key] = null;
740
+ changed = true;
741
+ };
742
+ for (const product of tempOrder.products || []) {
743
+ if (product.metadata && typeof product.metadata === "object") {
744
+ resetHolderField(product.metadata);
745
+ }
746
+ }
747
+ for (const booking of tempOrder.bookings || []) {
748
+ const bookingRecord = booking;
749
+ if (booking.metadata && typeof booking.metadata === "object") {
750
+ resetHolderField(booking.metadata);
751
+ }
752
+ if (bookingRecord.holder !== void 0 && bookingRecord.holder !== null) {
753
+ delete bookingRecord.holder;
754
+ changed = true;
755
+ }
756
+ }
757
+ const productsByUid = (_a = tempOrder._extend) == null ? void 0 : _a.productsByUid;
758
+ if (productsByUid && typeof productsByUid === "object") {
759
+ for (const entry of Object.values(productsByUid)) {
760
+ const origin = entry == null ? void 0 : entry.origin;
761
+ if (!origin || typeof origin !== "object")
762
+ continue;
763
+ if (origin.metadata && typeof origin.metadata === "object") {
764
+ resetHolderField(origin.metadata);
765
+ }
766
+ if (origin._extend && typeof origin._extend === "object") {
767
+ resetHolderField(origin._extend);
768
+ }
769
+ }
770
+ }
771
+ return changed;
772
+ }
723
773
  // Annotate the CommonJS export names for ESM import in node:
724
774
  0 && (module.exports = {
725
775
  buildManualProductDiscountItem,
726
776
  buildSubmitPayload,
777
+ clearTempOrderHolderAssignments,
727
778
  composeLinePrice,
728
779
  createDefaultOrderRulesHooks,
729
780
  createDefaultTempOrder,
@@ -735,6 +786,7 @@ function formatV1Product(products) {
735
786
  formatV1Product,
736
787
  generateDuration,
737
788
  getAllDiscountList,
789
+ hasAssignedHolderId,
738
790
  isTempOrder,
739
791
  mapPaymentItemToOrderPayment,
740
792
  mapPaymentItemsToOrderPayments,
@@ -47,7 +47,6 @@ export declare class QuotationModule extends BaseModule implements Module {
47
47
  customer_id?: number | string;
48
48
  }): Map<string, string | null>;
49
49
  setScheduleResolver(resolver: (id: number) => ScheduleItem | undefined): void;
50
- private filterQuotationsByCustomer;
51
50
  private isQuotationVisibleForCustomer;
52
51
  private hasValidCustomerId;
53
52
  private isQuotationActiveAt;
@@ -43,8 +43,6 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
43
43
  const query = {};
44
44
  if (params == null ? void 0 : params.channel)
45
45
  query.channel = params.channel;
46
- if (params == null ? void 0 : params.customer_id)
47
- query.customer_id = String(params.customer_id);
48
46
  if ((params == null ? void 0 : params.channel) === "online_store") {
49
47
  query.channel = "online-store";
50
48
  }
@@ -53,10 +51,7 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
53
51
  query,
54
52
  { useCache: false }
55
53
  );
56
- const list = this.filterQuotationsByCustomer(
57
- ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.list) || (res == null ? void 0 : res.list) || [],
58
- params == null ? void 0 : params.customer_id
59
- );
54
+ const list = ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.list) || (res == null ? void 0 : res.list) || [];
60
55
  list.sort((a, b) => a.sort - b.sort);
61
56
  this.store.list = list;
62
57
  }
@@ -130,9 +125,6 @@ var QuotationModule = class extends import_BaseModule.BaseModule {
130
125
  setScheduleResolver(resolver) {
131
126
  this.scheduleResolver = resolver;
132
127
  }
133
- filterQuotationsByCustomer(list, customerId) {
134
- return list.filter((quotation) => this.isQuotationVisibleForCustomer(quotation, customerId));
135
- }
136
128
  isQuotationVisibleForCustomer(quotation, customerId) {
137
129
  const customers = quotation.customer || [];
138
130
  if (customers.length === 0)
@@ -21,7 +21,7 @@ export declare class ProductsModule extends BaseModule implements Module {
21
21
  private isPriceFormatterRegistered;
22
22
  private quotationPriceBridge?;
23
23
  private quotationBridgeChannel?;
24
- private quotationBridgeCustomerId?;
24
+ private quotationBridgeLoadedKey?;
25
25
  private quotationBridgeRefreshPromise?;
26
26
  private quotationBridgeRefreshKey?;
27
27
  private productDataSource;
@@ -44,6 +44,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
44
44
  this.formatters = [];
45
45
  // 是否已注册内置价格格式化器
46
46
  this.isPriceFormatterRegistered = false;
47
+ this.quotationBridgeLoadedKey = "";
47
48
  this.pendingSyncMessages = [];
48
49
  }
49
50
  async initialize(core, options) {
@@ -190,14 +191,25 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
190
191
  this.quotationPriceBridge = quotation;
191
192
  }
192
193
  if (params.scheduleModule) {
194
+ const scheduleCache = /* @__PURE__ */ new Map();
195
+ let hasLoadedScheduleList = false;
193
196
  this.quotationPriceBridge.setScheduleResolver((id) => {
194
197
  var _a2, _b, _c, _d, _e, _f;
195
198
  const scheduleId = String(id);
196
- const scheduleList = ((_b = (_a2 = params.scheduleModule).getScheduleList) == null ? void 0 : _b.call(_a2)) || [];
197
- const schedule = scheduleList.find((item) => String(item.id) === scheduleId);
198
- if (schedule)
199
- return schedule;
199
+ if (scheduleCache.has(scheduleId))
200
+ return scheduleCache.get(scheduleId);
201
+ if (!hasLoadedScheduleList) {
202
+ const scheduleList = ((_b = (_a2 = params.scheduleModule).getScheduleList) == null ? void 0 : _b.call(_a2)) || [];
203
+ for (const schedule of scheduleList) {
204
+ scheduleCache.set(String(schedule.id), schedule);
205
+ }
206
+ hasLoadedScheduleList = true;
207
+ }
208
+ if (scheduleCache.has(scheduleId))
209
+ return scheduleCache.get(scheduleId);
200
210
  const schedules = ((_d = (_c = params.scheduleModule).getScheduleListByIds) == null ? void 0 : _d.call(_c, [id])) || ((_f = (_e = params.scheduleModule).getScheduleByIds) == null ? void 0 : _f.call(_e, [id])) || [];
211
+ if (schedules[0])
212
+ scheduleCache.set(scheduleId, schedules[0]);
201
213
  return schedules[0];
202
214
  });
203
215
  }
@@ -209,8 +221,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
209
221
  async refreshQuotationPriceBridge(params) {
210
222
  if (!this.quotationPriceBridge)
211
223
  return;
212
- const customerId = params && "customer_id" in params ? params.customer_id : this.quotationBridgeCustomerId;
213
- const refreshKey = this.getQuotationBridgeScopeKey(customerId);
224
+ const refreshKey = this.getQuotationBridgeScopeKey();
214
225
  if (this.quotationBridgeRefreshPromise && this.quotationBridgeRefreshKey === refreshKey) {
215
226
  await this.quotationBridgeRefreshPromise;
216
227
  return;
@@ -220,10 +231,9 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
220
231
  }
221
232
  this.quotationBridgeRefreshKey = refreshKey;
222
233
  this.quotationBridgeRefreshPromise = this.quotationPriceBridge.loadQuotations({
223
- channel: this.quotationBridgeChannel,
224
- customer_id: customerId
234
+ channel: this.quotationBridgeChannel
225
235
  }).then(() => {
226
- this.quotationBridgeCustomerId = customerId;
236
+ this.quotationBridgeLoadedKey = refreshKey;
227
237
  }).finally(() => {
228
238
  this.quotationBridgeRefreshPromise = void 0;
229
239
  this.quotationBridgeRefreshKey = void 0;
@@ -242,12 +252,12 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
242
252
  if (this.quotationBridgeRefreshPromise) {
243
253
  await this.quotationBridgeRefreshPromise;
244
254
  }
245
- if (this.getQuotationBridgeScopeKey(customerId) !== this.getQuotationBridgeScopeKey(this.quotationBridgeCustomerId)) {
255
+ if (this.getQuotationBridgeScopeKey() !== this.quotationBridgeLoadedKey) {
246
256
  await this.refreshQuotationPriceBridge({ customer_id: customerId });
247
257
  }
248
258
  }
249
- getQuotationBridgeScopeKey(customerId) {
250
- return `${this.quotationBridgeChannel || ""}:${customerId ?? ""}`;
259
+ getQuotationBridgeScopeKey() {
260
+ return this.quotationBridgeChannel || "";
251
261
  }
252
262
  buildPriceDataFromQuotation(product, datetime, customerId) {
253
263
  var _a;
@@ -257,10 +267,11 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
257
267
  customer_id: customerId
258
268
  });
259
269
  const productPrice = quotedPrice ?? product.price;
270
+ const productBasePrice = quotedPrice ?? product.base_price ?? product.price ?? 0;
260
271
  return {
261
272
  id: product.id,
262
273
  price: String(productPrice ?? 0),
263
- base_price: String(product.base_price ?? product.price ?? 0),
274
+ base_price: String(productBasePrice),
264
275
  variant: this.buildVariantPriceData(product, datetime, customerId),
265
276
  bundle_group: this.buildBundleGroupPriceData(product, datetime, customerId)
266
277
  };
@@ -277,7 +288,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
277
288
  customer_id: customerId
278
289
  });
279
290
  const price = quotedPrice ?? variant.price ?? product.price ?? 0;
280
- const basePrice = variant.base_price ?? variant.price ?? product.base_price ?? product.price ?? 0;
291
+ const basePrice = quotedPrice ?? variant.base_price ?? variant.price ?? product.base_price ?? product.price ?? 0;
281
292
  return {
282
293
  id: Number(variant.id),
283
294
  product_id: Number(variant.product_id ?? product.id),
@@ -302,7 +313,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
302
313
  customer_id: customerId
303
314
  });
304
315
  const price = quotedPrice ?? item.price ?? 0;
305
- const basePrice = item.base_price ?? item.price ?? 0;
316
+ const basePrice = quotedPrice ?? item.base_price ?? item.price ?? 0;
306
317
  return {
307
318
  id: Number(item.id),
308
319
  product_id: Number(item.product_id ?? product.id),
@@ -39,6 +39,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
39
39
  window: WindowPlugin;
40
40
  request: RequestPlugin;
41
41
  protected currentSalesDetail: ISalesDetail | null;
42
+ protected discountConfigCacheKey: string | null;
43
+ protected hasManualDiscountSelection: boolean;
42
44
  constructor(name?: string, version?: string);
43
45
  /**
44
46
  * 子类可覆盖此方法以追加/收敛要注册的子模块。
@@ -113,23 +115,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
113
115
  updateRemoteOrderNote(orderId: number | string, note: string): void;
114
116
  updateTempOrderShopDiscount(amount: string | number): string;
115
117
  updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
116
- /**
117
- * 运行时切换 tempOrder 是否写入 localStorage(委托 OrderModule)。
118
- * SalesSdk 等内存态场景可在挂载后设为 false,避免污染本地缓存。
119
- *
120
- * @example
121
- * bookingTicket.setEnableTempOrderPersist(false);
122
- * await bookingTicket.addProductToOrder(product);
123
- */
118
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
124
119
  setEnableTempOrderPersist(enabled: boolean): void;
125
- /**
126
- * 读取当前 tempOrder localStorage 持久化开关(委托 OrderModule)。
127
- *
128
- * @example
129
- * if (bookingTicket.isTempOrderPersistEnabled()) {
130
- * bookingTicket.restoreOrder();
131
- * }
132
- */
120
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
133
121
  isTempOrderPersistEnabled(): boolean;
134
122
  private ensureTempOrder;
135
123
  addNewOrder(): Promise<OrderTempOrder>;
@@ -57,6 +57,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
57
57
  this.otherParams = {};
58
58
  // 当前缓存中已加载的最新 SalesDetail;只读 getter 走它对外暴露详情数据。
59
59
  this.currentSalesDetail = null;
60
+ this.discountConfigCacheKey = null;
61
+ this.hasManualDiscountSelection = false;
60
62
  }
61
63
  /**
62
64
  * 子类可覆盖此方法以追加/收敛要注册的子模块。
@@ -417,30 +419,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
417
419
  throw new Error("order 模块未初始化");
418
420
  return this.store.order.updateTempOrderContactsInfo(contactsInfo);
419
421
  }
420
- /**
421
- * 运行时切换 tempOrder 是否写入 localStorage(委托 OrderModule)。
422
- * SalesSdk 等内存态场景可在挂载后设为 false,避免污染本地缓存。
423
- *
424
- * @example
425
- * bookingTicket.setEnableTempOrderPersist(false);
426
- * await bookingTicket.addProductToOrder(product);
427
- */
422
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
428
423
  setEnableTempOrderPersist(enabled) {
429
424
  if (!this.store.order)
430
425
  throw new Error("order 模块未初始化");
431
426
  this.store.order.setEnableTempOrderPersist(enabled);
432
427
  }
433
- /**
434
- * 读取当前 tempOrder localStorage 持久化开关(委托 OrderModule)。
435
- *
436
- * @example
437
- * if (bookingTicket.isTempOrderPersistEnabled()) {
438
- * bookingTicket.restoreOrder();
439
- * }
440
- */
428
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
441
429
  isTempOrderPersistEnabled() {
442
430
  if (!this.store.order)
443
- return true;
431
+ return false;
444
432
  return this.store.order.isTempOrderPersistEnabled();
445
433
  }
446
434
  ensureTempOrder() {
@@ -477,6 +465,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
477
465
  }
478
466
  const tempOrder = this.store.order.restoreOrder();
479
467
  this.currentSalesDetail = null;
468
+ this.discountConfigCacheKey = null;
469
+ this.hasManualDiscountSelection = false;
480
470
  await this.effectsEmit("onTempOrderReplaced", { tempOrder });
481
471
  if (this.syncAppDataToTempOrder(tempOrder)) {
482
472
  this.store.order.persistTempOrder();
@@ -615,7 +605,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
615
605
  });
616
606
  }
617
607
  async loadDiscountConfig(params) {
618
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
608
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
619
609
  if (!this.store.order)
620
610
  throw new Error("order 模块未初始化");
621
611
  const tempOrder = this.store.order.ensureTempOrder();
@@ -627,18 +617,37 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
627
617
  (params == null ? void 0 : params.customerId) || tempOrder.customer_id || ((_c = tempOrder.customer) == null ? void 0 : _c.id) || ((_e = (_d = tempOrder._extend) == null ? void 0 : _d.customerSnapshot) == null ? void 0 : _e.id) || ((_g = (_f = tempOrder._extend) == null ? void 0 : _f.customerSnapshot) == null ? void 0 : _g.customer_id) || 0
628
618
  );
629
619
  const currentDiscountList = ((_h = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _h.call(discountModule)) || [];
620
+ const originalDiscountList = ((_i = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _i.call(discountModule)) || [];
621
+ const hasManualDiscountSelection = this.hasManualDiscountSelection || currentDiscountList.some((discount) => discount.isManualSelect);
622
+ const discountAction = (params == null ? void 0 : params.action) || (orderId ? "edit" : "create");
623
+ const discountConfigCacheKey = [
624
+ customerId,
625
+ discountAction,
626
+ Number(orderId) || 0
627
+ ].join(":");
630
628
  let preparedDiscountList = [];
631
629
  if (customerId && customerId !== 1) {
632
- preparedDiscountList = await this.store.order.loadDiscountConfig({
633
- customerId,
634
- action: (params == null ? void 0 : params.action) || (orderId ? "edit" : "create"),
635
- orderId: Number(orderId) || void 0,
636
- apply: false
637
- });
638
- await ((_i = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _i.call(discountModule, preparedDiscountList));
630
+ if (this.discountConfigCacheKey === discountConfigCacheKey) {
631
+ preparedDiscountList = originalDiscountList;
632
+ } else {
633
+ preparedDiscountList = await this.store.order.loadDiscountConfig({
634
+ customerId,
635
+ action: discountAction,
636
+ orderId: Number(orderId) || void 0,
637
+ apply: false
638
+ });
639
+ this.discountConfigCacheKey = discountConfigCacheKey;
640
+ await ((_j = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _j.call(discountModule, preparedDiscountList));
641
+ }
642
+ }
643
+ if (hasManualDiscountSelection && currentDiscountList.length) {
644
+ return {
645
+ productList: tempOrder.products || [],
646
+ discountList: currentDiscountList
647
+ };
639
648
  }
640
649
  let nextDiscountList = this.mergeHistoricalDiscountList(
641
- preparedDiscountList || ((_j = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _j.call(discountModule)) || [],
650
+ preparedDiscountList || ((_k = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _k.call(discountModule)) || [],
642
651
  tempOrder.products || []
643
652
  );
644
653
  nextDiscountList = this.mergeCurrentDiscountSelectionState(
@@ -647,17 +656,39 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
647
656
  );
648
657
  await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
649
658
  if (rulesModule) {
650
- const holders = ((_k = tempOrder.holder) == null ? void 0 : _k.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
659
+ const holders = ((_l = tempOrder.holder) == null ? void 0 : _l.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
651
660
  const result = rulesModule.calcDiscount({
652
661
  productList: tempOrder.products,
653
662
  discountList: nextDiscountList,
654
663
  holders,
655
- isFormSubject: !!((_l = tempOrder.holder) == null ? void 0 : _l.type) && tempOrder.holder.type === "form",
656
- orderTotalAmount: Number(((_m = orderStore.summary) == null ? void 0 : _m.total_amount) || 0)
664
+ isFormSubject: !!((_m = tempOrder.holder) == null ? void 0 : _m.type) && tempOrder.holder.type === "form",
665
+ orderTotalAmount: Number(((_n = orderStore.summary) == null ? void 0 : _n.total_amount) || 0)
657
666
  }) || { productList: tempOrder.products, discountList: nextDiscountList };
658
667
  if (result.productList) {
659
668
  tempOrder.products = result.productList;
660
669
  }
670
+ for (const product of tempOrder.products || []) {
671
+ const productUid = (_o = product.metadata) == null ? void 0 : _o.unique_identification_number;
672
+ const runtimeOrigin = productUid ? (_r = (_q = (_p = tempOrder._extend) == null ? void 0 : _p.productsByUid) == null ? void 0 : _q[productUid]) == null ? void 0 : _r.origin : void 0;
673
+ if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || ((_s = product.metadata) == null ? void 0 : _s.is_manual_discount))
674
+ continue;
675
+ const totalPerUnitDiscount = (product.discount_list || []).reduce(
676
+ (sum, pd) => sum + Number(pd.amount || 0),
677
+ 0
678
+ );
679
+ const optionSum = (0, import_utils.sumOptionUnitPrice)(product.product_option_item);
680
+ const sourcePrice = ((_t = product.metadata) == null ? void 0 : _t.source_product_price) ?? (((_u = product.metadata) == null ? void 0 : _u.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");
681
+ const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
682
+ const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
683
+ if (product.metadata) {
684
+ product.metadata.main_product_selling_price = newMainSellingPrice;
685
+ product.metadata.price_schema_version = 2;
686
+ }
687
+ product.selling_price = (0, import_utils.composeLinePrice)({
688
+ mainPrice: newMainSellingPrice,
689
+ bundle: product.product_bundle
690
+ });
691
+ }
661
692
  if (result.discountList) {
662
693
  nextDiscountList = this.mergeHistoricalDiscountList(
663
694
  result.discountList,
@@ -668,6 +699,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
668
699
  tempOrder.discount_list = nextDiscountList.filter((discount) => discount.isSelected);
669
700
  }
670
701
  }
702
+ const summary = await this.store.order.recalculateSummary({ createIfMissing: true });
671
703
  this.store.order.persistTempOrder();
672
704
  await this.effectsEmit("onDiscountApplied", {
673
705
  productList: tempOrder.products || [],
@@ -681,7 +713,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
681
713
  };
682
714
  }
683
715
  async bestDiscount(cb) {
684
- var _a, _b, _c, _d;
716
+ var _a, _b, _c, _d, _e;
685
717
  if (!this.store.order)
686
718
  throw new Error("order 模块未初始化");
687
719
  const tempOrder = this.store.order.ensureTempOrder();
@@ -689,6 +721,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
689
721
  const discountModule = orderStore.discount;
690
722
  const rulesModule = orderStore.rules;
691
723
  const originalDiscountList = ((_a = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _a.call(discountModule)) || this.getDiscountList();
724
+ const currentDiscountList = ((_b = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
692
725
  let nextDiscountList = this.mergeHistoricalDiscountList(
693
726
  originalDiscountList || [],
694
727
  tempOrder.products || []
@@ -699,13 +732,13 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
699
732
  };
700
733
  await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
701
734
  if (rulesModule) {
702
- const holders = ((_b = tempOrder.holder) == null ? void 0 : _b.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
735
+ const holders = ((_c = tempOrder.holder) == null ? void 0 : _c.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
703
736
  result = rulesModule.calcDiscount({
704
737
  productList: tempOrder.products,
705
738
  discountList: nextDiscountList,
706
739
  holders,
707
- isFormSubject: !!((_c = tempOrder.holder) == null ? void 0 : _c.type) && tempOrder.holder.type === "form",
708
- orderTotalAmount: Number(((_d = orderStore.summary) == null ? void 0 : _d.total_amount) || 0)
740
+ isFormSubject: !!((_d = tempOrder.holder) == null ? void 0 : _d.type) && tempOrder.holder.type === "form",
741
+ orderTotalAmount: Number(((_e = orderStore.summary) == null ? void 0 : _e.total_amount) || 0)
709
742
  }) || result;
710
743
  if (result.productList) {
711
744
  tempOrder.products = result.productList;
@@ -766,6 +799,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
766
799
  isManualSelect: !params.isSelected
767
800
  } : d
768
801
  );
802
+ this.hasManualDiscountSelection = true;
769
803
  const tempOrder = this.store.order.ensureTempOrder();
770
804
  const orderStore = this.store.order.store || {};
771
805
  const discountModule = orderStore.discount;
@@ -798,6 +832,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
798
832
  for (const d of nextDiscountList) {
799
833
  if (d.isSelected && !beforeSelectedIds.has(d.id)) {
800
834
  d.isSelected = false;
835
+ d.isManualSelect = true;
801
836
  }
802
837
  }
803
838
  }
@@ -1000,11 +1035,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1000
1035
  return this.store.order.updateVoucherOrderPayments(payments);
1001
1036
  }
1002
1037
  getWalletProductList() {
1003
- var _a, _b;
1038
+ var _a, _b, _c;
1004
1039
  const tempOrder = (_a = this.store.order) == null ? void 0 : _a.getTempOrder();
1005
1040
  if (!((_b = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _b.length))
1006
1041
  return [];
1007
- return tempOrder.products.map((product) => {
1042
+ const products = (_c = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _c.filter((n) => n.product_id);
1043
+ return products.map((product) => {
1008
1044
  const metadata = product.metadata || {};
1009
1045
  return {
1010
1046
  product_id: product.product_id,
@@ -243,6 +243,19 @@ export interface BaseSalesProductBookingPriceSegment {
243
243
  quotation_shelf_id: number;
244
244
  source: BaseSalesProductBookingPriceSegmentSource;
245
245
  }
246
+ export interface BaseSalesBundleProductBookingPriceResult {
247
+ bundle_id?: number;
248
+ group_id?: number;
249
+ bundle_group_id?: number;
250
+ bundle_product_id: number | null;
251
+ bundle_variant_id: number;
252
+ unit_price: string;
253
+ total_price: string;
254
+ quantity: number;
255
+ quotation_shelf_id: number;
256
+ source: BaseSalesProductBookingPriceSegmentSource;
257
+ segments: BaseSalesProductBookingPriceSegment[];
258
+ }
246
259
  export interface BaseSalesProductBookingPriceResult {
247
260
  product_id: number | null;
248
261
  product_variant_id: number;
@@ -253,6 +266,7 @@ export interface BaseSalesProductBookingPriceResult {
253
266
  duration?: BaseSalesQuotationDurationConfig;
254
267
  quotation_shelf_id: number;
255
268
  segments: BaseSalesProductBookingPriceSegment[];
269
+ product_bundle?: BaseSalesBundleProductBookingPriceResult[];
256
270
  }
257
271
  export type BaseSalesAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
258
272
  export interface BaseSalesTableFormRecord {