@pisell/pisellos 0.10.8 → 0.10.9

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 (98) hide show
  1. package/dist/core/index.js +0 -1
  2. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.js +287 -101
  4. package/dist/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  5. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  6. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
  7. package/dist/model/strategy/adapter/walletPass/type.d.ts +5 -0
  8. package/dist/model/strategy/adapter/walletPass/utils.js +57 -26
  9. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  10. package/dist/modules/BookingContext/utils/productExtend.js +5 -9
  11. package/dist/modules/BookingContext/utils/timeSlices.js +24 -3
  12. package/dist/modules/Customer/index.d.ts +4 -0
  13. package/dist/modules/Customer/index.js +91 -59
  14. package/dist/modules/Customer/types.d.ts +2 -0
  15. package/dist/modules/Discount/index.d.ts +2 -0
  16. package/dist/modules/Discount/index.js +38 -5
  17. package/dist/modules/Discount/types.d.ts +11 -0
  18. package/dist/modules/Order/index.d.ts +20 -1
  19. package/dist/modules/Order/index.js +976 -730
  20. package/dist/modules/Order/types.d.ts +6 -1
  21. package/dist/modules/Order/utils/virtualSettlement.d.ts +56 -0
  22. package/dist/modules/Order/utils/virtualSettlement.js +271 -0
  23. package/dist/modules/Order/utils.js +89 -48
  24. package/dist/modules/Payment/types.d.ts +2 -0
  25. package/dist/modules/Payment/utils.js +4 -1
  26. package/dist/modules/Payment/walletpass.d.ts +11 -0
  27. package/dist/modules/Payment/walletpass.js +235 -60
  28. package/dist/modules/Product/types.d.ts +23 -0
  29. package/dist/modules/ProductList/index.d.ts +15 -2
  30. package/dist/modules/ProductList/index.js +92 -13
  31. package/dist/modules/SalesSummary/index.d.ts +1 -0
  32. package/dist/modules/SalesSummary/index.js +4 -3
  33. package/dist/modules/SalesSummary/types.d.ts +1 -0
  34. package/dist/modules/SalesSummary/utils.d.ts +1 -0
  35. package/dist/modules/SalesSummary/utils.js +21 -1
  36. package/dist/server/index.d.ts +9 -0
  37. package/dist/server/index.js +90 -58
  38. package/dist/server/modules/order/index.d.ts +1 -0
  39. package/dist/server/modules/order/index.js +252 -94
  40. package/dist/server/utils/small-ticket.js +2 -1
  41. package/dist/solution/BaseSales/index.d.ts +26 -2
  42. package/dist/solution/BaseSales/index.js +1310 -931
  43. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  44. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +78 -12
  45. package/dist/solution/BookingByStep/index.d.ts +3 -3
  46. package/dist/solution/BookingTicket/index.d.ts +5 -1
  47. package/dist/solution/BookingTicket/index.js +221 -159
  48. package/dist/solution/BookingTicket/utils/addProductDecision.js +2 -1
  49. package/dist/solution/ScanOrder/index.js +25 -64
  50. package/lib/core/index.js +0 -1
  51. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  52. package/lib/model/strategy/adapter/dataVariant/evaluator.js +170 -7
  53. package/lib/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  54. package/lib/model/strategy/adapter/walletPass/evaluator.js +0 -2
  55. package/lib/model/strategy/adapter/walletPass/type.d.ts +5 -0
  56. package/lib/model/strategy/adapter/walletPass/utils.js +62 -11
  57. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  58. package/lib/modules/BookingContext/utils/productExtend.js +4 -3
  59. package/lib/modules/BookingContext/utils/timeSlices.js +18 -3
  60. package/lib/modules/Customer/index.d.ts +4 -0
  61. package/lib/modules/Customer/index.js +11 -0
  62. package/lib/modules/Customer/types.d.ts +2 -0
  63. package/lib/modules/Discount/index.d.ts +2 -0
  64. package/lib/modules/Discount/index.js +37 -3
  65. package/lib/modules/Discount/types.d.ts +11 -0
  66. package/lib/modules/Order/index.d.ts +20 -1
  67. package/lib/modules/Order/index.js +393 -128
  68. package/lib/modules/Order/types.d.ts +6 -1
  69. package/lib/modules/Order/utils/virtualSettlement.d.ts +56 -0
  70. package/lib/modules/Order/utils/virtualSettlement.js +300 -0
  71. package/lib/modules/Order/utils.js +65 -21
  72. package/lib/modules/Payment/types.d.ts +2 -0
  73. package/lib/modules/Payment/utils.js +5 -1
  74. package/lib/modules/Payment/walletpass.d.ts +11 -0
  75. package/lib/modules/Payment/walletpass.js +198 -17
  76. package/lib/modules/Product/types.d.ts +23 -0
  77. package/lib/modules/ProductList/index.d.ts +15 -2
  78. package/lib/modules/ProductList/index.js +85 -3
  79. package/lib/modules/SalesSummary/index.d.ts +1 -0
  80. package/lib/modules/SalesSummary/index.js +10 -2
  81. package/lib/modules/SalesSummary/types.d.ts +1 -0
  82. package/lib/modules/SalesSummary/utils.d.ts +1 -0
  83. package/lib/modules/SalesSummary/utils.js +25 -1
  84. package/lib/server/index.d.ts +9 -0
  85. package/lib/server/index.js +54 -14
  86. package/lib/server/modules/order/index.d.ts +1 -0
  87. package/lib/server/modules/order/index.js +66 -2
  88. package/lib/server/utils/small-ticket.js +1 -1
  89. package/lib/solution/BaseSales/index.d.ts +26 -2
  90. package/lib/solution/BaseSales/index.js +261 -23
  91. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  92. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +61 -11
  93. package/lib/solution/BookingByStep/index.d.ts +3 -3
  94. package/lib/solution/BookingTicket/index.d.ts +5 -1
  95. package/lib/solution/BookingTicket/index.js +30 -2
  96. package/lib/solution/BookingTicket/utils/addProductDecision.js +2 -1
  97. package/lib/solution/ScanOrder/index.js +17 -54
  98. package/package.json +1 -1
@@ -43,6 +43,21 @@ __export(utils_exports, {
43
43
  });
44
44
  module.exports = __toCommonJS(utils_exports);
45
45
  var import_decimal = __toESM(require("decimal.js"));
46
+ var DEFAULT_WALLET_PASS_CALCULATION_CONFIG = {
47
+ maxDeductionAmount: 99999,
48
+ maxUsagePerOrder: 0,
49
+ allowCrossProduct: true,
50
+ applicableProductLimit: 0,
51
+ deductTaxAndFee: true,
52
+ maxPassesPerItem: 0,
53
+ deductOptionPrice: false
54
+ };
55
+ function getWalletPassCalculationConfig(voucher) {
56
+ return {
57
+ ...DEFAULT_WALLET_PASS_CALCULATION_CONFIG,
58
+ ...(voucher == null ? void 0 : voucher.config) || {}
59
+ };
60
+ }
46
61
  var getProductQuantity = (product) => {
47
62
  return product.quantity || product.product_quantity || 1;
48
63
  };
@@ -105,9 +120,15 @@ function applyMaxPassUsageIncrements(usageMap, walletPassProductId, maxPassesPer
105
120
  });
106
121
  }
107
122
  var getRecommendedAmount = (voucher) => {
108
- console.log("voucher312", voucher);
109
123
  const { config, recommended_usage_amount, recommended_pure_product_usage_amount } = voucher;
110
124
  const deductTaxAndFee = (config == null ? void 0 : config.deductTaxAndFee) ?? true;
125
+ const rawRecalculationBaseAmount = voucher._wallet_asset_recalculation_base_amount;
126
+ if (rawRecalculationBaseAmount !== void 0 && rawRecalculationBaseAmount !== null) {
127
+ const recalculationBaseAmount = Number(rawRecalculationBaseAmount);
128
+ if (Number.isFinite(recalculationBaseAmount) && recalculationBaseAmount >= 0) {
129
+ return recalculationBaseAmount;
130
+ }
131
+ }
111
132
  return deductTaxAndFee ? recommended_usage_amount : recommended_pure_product_usage_amount ?? recommended_usage_amount;
112
133
  };
113
134
  var getApplicableProductIds = (voucher) => {
@@ -145,7 +166,6 @@ var getApplicableProducts = (voucher, productsData) => {
145
166
  return productsData.filter((p) => applicableProductIds.includes(p.product_id));
146
167
  };
147
168
  function processVouchers(applicableVouchers, orderTotalAmount, products) {
148
- console.log(products, "products123");
149
169
  const productsCopy = expandProductsWithBundleItems(products, true);
150
170
  let remainingOrderAmount = new import_decimal.default(orderTotalAmount);
151
171
  const getItemPassUsage = (usageMap, walletPassProductId, lineKey) => {
@@ -218,7 +238,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
218
238
  return import_decimal.default.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
219
239
  };
220
240
  const isVoucherAvailable = (voucher, productsData, usedVoucherCounts2, itemPassUsage) => {
221
- const { config, id, product_id } = voucher;
241
+ const { config, product_id } = voucher;
222
242
  const recommendedAmount = getRecommendedAmount(voucher);
223
243
  if (recommendedAmount <= 0) {
224
244
  return { isAvailable: false, reasonCode: "not_meet_the_required_conditions" };
@@ -453,6 +473,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
453
473
  const productsForCalc = expandProductsWithBundleItems(products, true);
454
474
  let remainingOrderAmount = new import_decimal.default(orderTotalAmount);
455
475
  const selectedWithDetails = [];
476
+ const usedVoucherCounts = /* @__PURE__ */ new Map();
456
477
  const itemPassUsageMap = /* @__PURE__ */ new Map();
457
478
  const getItemPassUsageRecalc = (walletPassProductId, lineKey) => {
458
479
  var _a;
@@ -469,8 +490,29 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
469
490
  });
470
491
  };
471
492
  selectedVouchers.forEach((selectedVoucher) => {
472
- const { config, id } = selectedVoucher;
473
- const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true, maxPassesPerItem = 0 } = config;
493
+ const { product_id } = selectedVoucher;
494
+ const config = getWalletPassCalculationConfig(selectedVoucher);
495
+ const {
496
+ maxDeductionAmount,
497
+ maxUsagePerOrder,
498
+ allowCrossProduct,
499
+ applicableProductLimit,
500
+ deductTaxAndFee,
501
+ maxPassesPerItem
502
+ } = config;
503
+ const usedCount = usedVoucherCounts.get(product_id) || 0;
504
+ if (maxUsagePerOrder > 0 && usedCount >= maxUsagePerOrder) {
505
+ selectedWithDetails.push({
506
+ ...selectedVoucher,
507
+ config,
508
+ actualDeduction: 0,
509
+ deductionDetails: [],
510
+ _available_max_amount: 0,
511
+ _unified_available_status: 0,
512
+ reasonCode: "usage_limit_reached"
513
+ });
514
+ return;
515
+ }
474
516
  const unitPriceField = deductTaxAndFee ? "unitPriceWithTax" : "unitPricePure";
475
517
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
476
518
  let applicableProducts = getApplicableProducts(
@@ -481,6 +523,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
481
523
  if (applicableProducts.length === 0) {
482
524
  selectedWithDetails.push({
483
525
  ...selectedVoucher,
526
+ config,
484
527
  actualDeduction: 0,
485
528
  deductionDetails: [],
486
529
  _available_max_amount: 0,
@@ -558,6 +601,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
558
601
  applyMaxPassUsageIncrements(itemPassUsageMap, selectedVoucher.product_id, maxPassesPerItem, deductionDetails);
559
602
  selectedWithDetails.push({
560
603
  ...selectedVoucher,
604
+ config,
561
605
  actualDeduction: totalDeducted.toNumber(),
562
606
  // 转换为数字
563
607
  deductionDetails,
@@ -565,12 +609,11 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
565
609
  // 转换为数字
566
610
  _unified_available_status: totalDeducted.greaterThan(0) ? 1 : 0
567
611
  });
612
+ if (totalDeducted.greaterThan(0)) {
613
+ usedVoucherCounts.set(product_id, usedCount + 1);
614
+ }
568
615
  });
569
616
  const selectedIds = new Set(selectedVouchers.map((v) => v.id));
570
- const usedVoucherCounts = /* @__PURE__ */ new Map();
571
- selectedVouchers.forEach((v) => {
572
- usedVoucherCounts.set(v.product_id, (usedVoucherCounts.get(v.product_id) || 0) + 1);
573
- });
574
617
  const allWithUpdatedStatus = allVouchers.map((voucher) => {
575
618
  if (selectedIds.has(voucher.id)) {
576
619
  const selectedDetail = selectedWithDetails.find(
@@ -578,8 +621,15 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
578
621
  );
579
622
  return selectedDetail || voucher;
580
623
  }
581
- const { config, id, product_id } = voucher;
582
- const { maxDeductionAmount, allowCrossProduct, applicableProductLimit, deductTaxAndFee = true, maxPassesPerItem = 0 } = config;
624
+ const { product_id } = voucher;
625
+ const config = getWalletPassCalculationConfig(voucher);
626
+ const {
627
+ maxDeductionAmount,
628
+ allowCrossProduct,
629
+ applicableProductLimit,
630
+ deductTaxAndFee,
631
+ maxPassesPerItem
632
+ } = config;
583
633
  const unitPriceField = deductTaxAndFee ? "unitPriceWithTax" : "unitPricePure";
584
634
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
585
635
  const recommendedAmount = getRecommendedAmount(voucher);
@@ -663,6 +713,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
663
713
  }
664
714
  return {
665
715
  ...voucher,
716
+ config,
666
717
  _available_max_amount: calculatedMaxAmount.toNumber(),
667
718
  // 转换为数字
668
719
  _unified_available_status: isAvailable ? 1 : 0,
@@ -202,6 +202,8 @@ function buildCacheItemFromOrderLine(input) {
202
202
  const productTitle = resolveProductTitle(product, booking, sourceProduct);
203
203
  const productCover = resolveProductCover(product, booking, sourceProduct);
204
204
  const productOptionString = (0, import_orderLineDisplay.buildProductOptionStringFromOrderLine)(product);
205
+ const hasBundle = Array.isArray(product.product_bundle) && product.product_bundle.length > 0;
206
+ const bundleEdit = product.bundle_edit ?? (hasBundle ? 0 : void 0);
205
207
  const other = {
206
208
  product_variant_id: product.product_variant_id ?? 0,
207
209
  option: (0, import_utils.getProductSkuOptions)(product),
@@ -234,6 +236,7 @@ function buildCacheItemFromOrderLine(input) {
234
236
  product.discount_list,
235
237
  (_c = product.metadata) == null ? void 0 : _c.product_discount_reason
236
238
  ) || void 0,
239
+ ...bundleEdit !== void 0 ? { bundle_edit: bundleEdit } : {},
237
240
  ...productOptionString ? { product_option_string: productOptionString } : {}
238
241
  };
239
242
  const manualDiscount = (product.discount_list || []).find((d) => (d == null ? void 0 : d.type) === "product");
@@ -83,12 +83,13 @@ function getTimeObj(params) {
83
83
  const { cacheItem, useStartTime, useDuration, ctx } = params;
84
84
  const isMultiDay = (0, import_serviceTimes.isMultiDayProduct)(cacheItem);
85
85
  const flexibleOption = getFlexibleOption({ cacheItem, useStartTime, ctx });
86
- const baseSlices = (0, import_timeSlices.sliceDayIntoFiveMinutes)(
86
+ const {
87
+ timeSlices,
88
+ durationSlicesBasedOnTime
89
+ } = (0, import_timeSlices.sliceDayIntoFiveMinutes)(
87
90
  (_c = (_b = (_a = ctx == null ? void 0 : ctx.bookingConfig) == null ? void 0 : _a.config) == null ? void 0 : _b.basic) == null ? void 0 : _c.service_time,
88
91
  isMultiDay
89
92
  );
90
- const timeSlices = [...baseSlices.timeSlices];
91
- const durationSlicesBasedOnTime = [...baseSlices.durationSlicesBasedOnTime];
92
93
  if (flexibleOption) {
93
94
  durationSlicesBasedOnTime.unshift(flexibleOption);
94
95
  }
@@ -38,10 +38,21 @@ __export(timeSlices_exports, {
38
38
  module.exports = __toCommonJS(timeSlices_exports);
39
39
  var import_dayjs = __toESM(require("dayjs"));
40
40
  var import_flexible = require("./flexible");
41
+ var timeSlicesCache = /* @__PURE__ */ new Map();
42
+ function copyTimeSlices(result) {
43
+ return {
44
+ timeSlices: [...result.timeSlices],
45
+ durationSlicesBasedOnTime: [...result.durationSlicesBasedOnTime]
46
+ };
47
+ }
41
48
  function sliceDayIntoFiveMinutes(config, isDay) {
49
+ const timeSlice = config && config.value || 5;
50
+ const cacheKey = isDay ? "days" : `minutes:${timeSlice}`;
51
+ const cached = timeSlicesCache.get(cacheKey);
52
+ if (cached)
53
+ return copyTimeSlices(cached);
42
54
  const startTime = (0, import_dayjs.default)().startOf("day");
43
55
  const endTime = (0, import_dayjs.default)().endOf("day");
44
- const timeSlice = config && config.value || 5;
45
56
  const timeSlices = [];
46
57
  const durationSlicesBasedOnTime = [];
47
58
  let currentTime = startTime;
@@ -58,7 +69,9 @@ function sliceDayIntoFiveMinutes(config, isDay) {
58
69
  });
59
70
  currentDay += 1;
60
71
  }
61
- return { timeSlices, durationSlicesBasedOnTime };
72
+ const result2 = { timeSlices, durationSlicesBasedOnTime };
73
+ timeSlicesCache.set(cacheKey, result2);
74
+ return copyTimeSlices(result2);
62
75
  }
63
76
  while (currentTime.isBefore(endTime)) {
64
77
  timeSlices.push({
@@ -73,7 +86,9 @@ function sliceDayIntoFiveMinutes(config, isDay) {
73
86
  });
74
87
  currentTime = nextTime;
75
88
  }
76
- return { timeSlices, durationSlicesBasedOnTime };
89
+ const result = { timeSlices, durationSlicesBasedOnTime };
90
+ timeSlicesCache.set(cacheKey, result);
91
+ return copyTimeSlices(result);
77
92
  }
78
93
  function findNextDuration(current, array, defaultValue) {
79
94
  if (defaultValue !== void 0 && defaultValue !== null)
@@ -44,6 +44,10 @@ export declare class CustomerModule extends BaseModule implements Module, Custom
44
44
  * 用于按 ID 补齐客户等内部查询,避免把临时的 num/searchParams 污染到滚动列表。
45
45
  */
46
46
  queryCustomerList(params?: ShopGetCustomerListParams): Promise<ICustomerListResponse>;
47
+ /**
48
+ * 查询单个客户详情,不写入 customerList / pagination 状态。
49
+ */
50
+ queryCustomerDetail(id: string | number): Promise<ShopCustomer | null>;
47
51
  /**
48
52
  * 获取客户列表
49
53
  * @param params 查询参数
@@ -201,6 +201,17 @@ var CustomerModule = class extends import_BaseModule.BaseModule {
201
201
  pageSize
202
202
  };
203
203
  }
204
+ /**
205
+ * 查询单个客户详情,不写入 customerList / pagination 状态。
206
+ */
207
+ async queryCustomerDetail(id) {
208
+ var _a;
209
+ const result = await this.request.get(`/customer/info/${id}`, {
210
+ with_trashed: 1
211
+ });
212
+ const customer = ((_a = result == null ? void 0 : result.data) == null ? void 0 : _a.customer) || (result == null ? void 0 : result.data) || (result == null ? void 0 : result.customer) || null;
213
+ return customer && typeof customer === "object" ? customer : null;
214
+ }
204
215
  /**
205
216
  * 获取客户列表
206
217
  * @param params 查询参数
@@ -112,6 +112,8 @@ export interface CustomerModuleAPI {
112
112
  getCustomerList: (params?: ShopGetCustomerListParams) => Promise<ICustomerListResponse>;
113
113
  /** 查询客户列表但不更新列表分页状态 */
114
114
  queryCustomerList: (params?: ShopGetCustomerListParams) => Promise<ICustomerListResponse>;
115
+ /** 查询单个客户详情但不修改客户列表状态 */
116
+ queryCustomerDetail: (id: string | number) => Promise<ShopCustomer | null>;
115
117
  /** 设置客户列表 */
116
118
  setCustomerList: (customers: ShopCustomer[], total?: number) => void;
117
119
  /** 设置当前选择的客户 */
@@ -25,9 +25,11 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
25
25
  with_wallet_pass_holder: 0 | 1;
26
26
  with_available_wallet_flag?: 0 | 1;
27
27
  with_available_wallet_pass_flag?: 0 | 1;
28
+ with_virtual_currency?: 0 | 1;
28
29
  request_timezone: string;
29
30
  order_id?: number | string;
30
31
  }): Promise<DiscountPrepareConfigResult>;
32
+ private normalizeVirtualCurrencyList;
31
33
  batchSearch(code: string, options?: {
32
34
  customerId?: number;
33
35
  orderId?: number;
@@ -96,7 +96,7 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
96
96
  return Array.from(new Set(ids));
97
97
  }
98
98
  async loadPrepareConfig(params) {
99
- var _a, _b, _c, _d, _e;
99
+ var _a, _b, _c, _d, _e, _f;
100
100
  if (typeof params.order_id === "string" && params.order_id.startsWith("LOCAL_")) {
101
101
  params.order_id = void 0;
102
102
  }
@@ -105,7 +105,8 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
105
105
  {
106
106
  ...params,
107
107
  with_available_wallet_flag: params.with_available_wallet_flag ?? 1,
108
- with_available_wallet_pass_flag: params.with_available_wallet_pass_flag ?? 1
108
+ with_available_wallet_pass_flag: params.with_available_wallet_pass_flag ?? 1,
109
+ with_virtual_currency: params.with_virtual_currency ?? 1
109
110
  }
110
111
  );
111
112
  const rawDiscountList = [
@@ -121,14 +122,47 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
121
122
  ...availableWalletList.map((item) => item == null ? void 0 : item.wallet_id),
122
123
  ...availableWalletPassList.map((item) => item == null ? void 0 : item.product_id)
123
124
  ]);
125
+ const virtualCurrencyList = this.normalizeVirtualCurrencyList(
126
+ (_f = prepareConfig == null ? void 0 : prepareConfig.data) == null ? void 0 : _f.virtual_currency_list
127
+ );
124
128
  const goodPassList = this.filterEnabledDiscountList(
125
129
  rawDiscountList
126
130
  ) || [];
127
131
  return {
128
132
  discountList: goodPassList,
129
- availableWalletIds
133
+ availableWalletIds,
134
+ virtualCurrencyList
130
135
  };
131
136
  }
137
+ normalizeVirtualCurrencyList(value) {
138
+ if (!Array.isArray(value))
139
+ return [];
140
+ return value.flatMap((item) => {
141
+ const id = Number(item == null ? void 0 : item.id);
142
+ const productId = Number(item == null ? void 0 : item.product_id);
143
+ if (!Number.isFinite(id) || id <= 0 || !Number.isFinite(productId) || productId <= 0) {
144
+ return [];
145
+ }
146
+ const displayExtension = Array.isArray(item == null ? void 0 : item.extension_data) ? item.extension_data.find(
147
+ (extension) => (extension == null ? void 0 : extension.field_key) === "virtual_currency_display"
148
+ ) : void 0;
149
+ let display = displayExtension == null ? void 0 : displayExtension.value;
150
+ if (typeof display === "string") {
151
+ try {
152
+ display = JSON.parse(display);
153
+ } catch {
154
+ display = {};
155
+ }
156
+ }
157
+ return [{
158
+ ...item,
159
+ id,
160
+ product_id: productId,
161
+ balance: String((item == null ? void 0 : item.balance) ?? "0"),
162
+ virtual_currency_display: display && typeof display === "object" && !Array.isArray(display) ? display : {}
163
+ }];
164
+ });
165
+ }
132
166
  async batchSearch(code, options) {
133
167
  const { customerId, orderId } = options || {};
134
168
  const result = await this.request.get(`/machinecode/batch-search`, {
@@ -71,6 +71,17 @@ export interface DiscountWithReason {
71
71
  export interface DiscountPrepareConfigResult {
72
72
  discountList: Discount[];
73
73
  availableWalletIds: number[];
74
+ virtualCurrencyList?: VirtualCurrencyAsset[];
75
+ }
76
+ export interface VirtualCurrencyAsset extends Record<string, any> {
77
+ id: number;
78
+ product_id: number;
79
+ balance: string;
80
+ product_name?: string;
81
+ format_title?: Record<string, any>;
82
+ code?: string;
83
+ encoded?: string;
84
+ virtual_currency_display?: Record<string, any>;
74
85
  }
75
86
  interface ExtensionData {
76
87
  id: number;
@@ -82,6 +82,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
82
82
  }): Promise<Discount[]>;
83
83
  getDiscountList(): Discount[];
84
84
  getAvailableWalletIds(): number[];
85
+ getVirtualCurrencyList(): import("../Discount/types").VirtualCurrencyAsset[];
85
86
  private syncScannedDiscountsToOriginalDiscountList;
86
87
  private ensureEditDiscountConfigForProductChange;
87
88
  scanCode(code: string, customerId?: number): Promise<{
@@ -195,6 +196,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
195
196
  orderExpectedAmount: string;
196
197
  };
197
198
  private calculateDepositPaidAmount;
199
+ private hasPaidNormalPayment;
198
200
  private resolveNextOrderPaymentType;
199
201
  private getPaymentNumberAppData;
200
202
  private getPaymentNumberDevicePrefixSync;
@@ -372,6 +374,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
372
374
  updateVoucherOrderPaymentsAsync(payments: OrderPaymentSource[], options?: {
373
375
  status?: 'paid' | 'payment_pending';
374
376
  }): Promise<OrderPaymentData[]>;
377
+ private normalizeShouldMergeProductResult;
375
378
  private shouldMergeProductToOrder;
376
379
  private hasOrderProductLineNote;
377
380
  /**
@@ -381,6 +384,13 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
381
384
  * this.hasLinkedBookingUid({ metadata: { booking_uid: 'booking-1' } });
382
385
  */
383
386
  private hasLinkedBookingUid;
387
+ private isMultiCurrencySettlementEnabled;
388
+ private isActiveVirtualSettlementOrder;
389
+ private shouldUseVirtualSettlementSummary;
390
+ private normalizeVirtualSettlementProductIfEnabled;
391
+ private assertAndLockProductSettlement;
392
+ private syncTempOrderSettlementState;
393
+ private prepareVirtualSettlementTempOrder;
384
394
  /**
385
395
  * 预约商品加车后的统一收尾:促销、折扣、summary 重算与持久化(批量拆行时只调用一次)。
386
396
  *
@@ -393,7 +403,12 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
393
403
  * 带 booking 且 num>1 时由 `addProductToOrder` 拆成多次本方法调用(每次 num=1)。
394
404
  *
395
405
  * @example
396
- * await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
406
+ * const pending = this.appendProductLineToTempOrder(
407
+ * tempOrder,
408
+ * { product_id: 1, num: 1 },
409
+ * booking,
410
+ * );
411
+ * if (pending) await pending;
397
412
  */
398
413
  private appendProductLineToTempOrder;
399
414
  /**
@@ -448,6 +463,10 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
448
463
  * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
449
464
  */
450
465
  clearOrderCartLines(): Promise<OrderTempOrder>;
466
+ /**
467
+ * 切换购物车结算单位时清理所有会影响新币种的订单状态,但保留当前客户。
468
+ */
469
+ clearOrderForSettlementSwitch(): Promise<OrderTempOrder>;
451
470
  buildCurrentSubmitPayloadForLocalPrint(params?: {
452
471
  cacheId?: string;
453
472
  platform?: string;