@pisell/pisellos 2.2.309 → 2.2.310

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 (121) hide show
  1. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  2. package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
  3. package/dist/modules/BookingContext/index.js +4 -4
  4. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +58 -19
  5. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +24 -12
  6. package/dist/modules/Customer/index.js +6 -3
  7. package/dist/modules/Customer/types.d.ts +2 -0
  8. package/dist/modules/Discount/availability.d.ts +7 -0
  9. package/dist/modules/Discount/availability.js +49 -0
  10. package/dist/modules/Discount/entitlementPass.d.ts +34 -0
  11. package/dist/modules/Discount/entitlementPass.js +147 -0
  12. package/dist/modules/Discount/index.d.ts +2 -2
  13. package/dist/modules/Discount/index.js +37 -151
  14. package/dist/modules/Discount/types.d.ts +36 -5
  15. package/dist/modules/OpenData/index.d.ts +1 -1
  16. package/dist/modules/OpenData/index.js +21 -12
  17. package/dist/modules/Order/index.d.ts +32 -4
  18. package/dist/modules/Order/index.js +733 -373
  19. package/dist/modules/Order/types.d.ts +17 -0
  20. package/dist/modules/Order/utils/orderCollectionIdentity.js +16 -12
  21. package/dist/modules/Order/utils.d.ts +14 -2
  22. package/dist/modules/Order/utils.js +275 -76
  23. package/dist/modules/Payment/index.d.ts +0 -5
  24. package/dist/modules/Payment/index.js +35 -85
  25. package/dist/modules/Payment/types.d.ts +21 -1
  26. package/dist/modules/Payment/types.js +2 -0
  27. package/dist/modules/Payment/walletpass.d.ts +1 -1
  28. package/dist/modules/Payment/walletpass.js +80 -47
  29. package/dist/modules/ProductList/index.js +18 -5
  30. package/dist/modules/Rules/index.d.ts +2 -2
  31. package/dist/modules/Rules/index.js +480 -186
  32. package/dist/modules/Rules/types.d.ts +4 -0
  33. package/dist/server/index.js +8 -5
  34. package/dist/server/modules/order/index.js +6 -0
  35. package/dist/server/modules/order/types.d.ts +12 -0
  36. package/dist/server/modules/payment/index.d.ts +25 -6
  37. package/dist/server/modules/payment/index.js +660 -133
  38. package/dist/server/utils/small-ticket.d.ts +8 -5
  39. package/dist/server/utils/small-ticket.js +1269 -199
  40. package/dist/solution/BaseSales/index.d.ts +11 -2
  41. package/dist/solution/BaseSales/index.js +1463 -1173
  42. package/dist/solution/BaseSales/types.d.ts +7 -3
  43. package/dist/solution/BaseSales/utils/cartPromotion.js +141 -126
  44. package/dist/solution/BookingByStep/index.d.ts +1 -1
  45. package/dist/solution/BookingTicket/index.d.ts +12 -3
  46. package/dist/solution/BookingTicket/index.js +663 -542
  47. package/dist/solution/BookingTicket/types.d.ts +5 -1
  48. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
  49. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +338 -147
  50. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
  51. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
  52. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +19 -6
  53. package/dist/solution/ShopDiscount/index.d.ts +2 -0
  54. package/dist/solution/ShopDiscount/index.js +99 -42
  55. package/dist/solution/ShopDiscount/utils.d.ts +4 -2
  56. package/dist/solution/ShopDiscount/utils.js +43 -23
  57. package/dist/solution/UnifiedBookingSales/index.d.ts +2 -2
  58. package/dist/solution/UnifiedBookingSales/index.js +5 -5
  59. package/dist/utils/os-private-payload.d.ts +5 -0
  60. package/dist/utils/os-private-payload.js +17 -0
  61. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  62. package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
  63. package/lib/modules/BookingContext/index.js +3 -3
  64. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +35 -6
  65. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +13 -6
  66. package/lib/modules/Customer/index.js +5 -1
  67. package/lib/modules/Customer/types.d.ts +2 -0
  68. package/lib/modules/Discount/availability.d.ts +7 -0
  69. package/lib/modules/Discount/availability.js +43 -0
  70. package/lib/modules/Discount/entitlementPass.d.ts +34 -0
  71. package/lib/modules/Discount/entitlementPass.js +141 -0
  72. package/lib/modules/Discount/index.d.ts +2 -2
  73. package/lib/modules/Discount/index.js +23 -129
  74. package/lib/modules/Discount/types.d.ts +36 -5
  75. package/lib/modules/OpenData/index.d.ts +1 -1
  76. package/lib/modules/OpenData/index.js +11 -2
  77. package/lib/modules/Order/index.d.ts +32 -4
  78. package/lib/modules/Order/index.js +341 -71
  79. package/lib/modules/Order/types.d.ts +17 -0
  80. package/lib/modules/Order/utils/orderCollectionIdentity.js +14 -11
  81. package/lib/modules/Order/utils.d.ts +14 -2
  82. package/lib/modules/Order/utils.js +186 -3
  83. package/lib/modules/Payment/index.d.ts +0 -5
  84. package/lib/modules/Payment/index.js +3 -28
  85. package/lib/modules/Payment/types.d.ts +21 -1
  86. package/lib/modules/Payment/types.js +1 -0
  87. package/lib/modules/Payment/walletpass.d.ts +1 -1
  88. package/lib/modules/Payment/walletpass.js +29 -9
  89. package/lib/modules/ProductList/index.js +14 -1
  90. package/lib/modules/Rules/index.d.ts +2 -2
  91. package/lib/modules/Rules/index.js +357 -110
  92. package/lib/modules/Rules/types.d.ts +4 -0
  93. package/lib/server/index.js +8 -5
  94. package/lib/server/modules/order/index.js +6 -0
  95. package/lib/server/modules/order/types.d.ts +12 -0
  96. package/lib/server/modules/payment/index.d.ts +25 -6
  97. package/lib/server/modules/payment/index.js +350 -78
  98. package/lib/server/utils/small-ticket.d.ts +8 -5
  99. package/lib/server/utils/small-ticket.js +1009 -121
  100. package/lib/solution/BaseSales/index.d.ts +11 -2
  101. package/lib/solution/BaseSales/index.js +164 -30
  102. package/lib/solution/BaseSales/types.d.ts +7 -3
  103. package/lib/solution/BaseSales/utils/cartPromotion.js +12 -4
  104. package/lib/solution/BookingByStep/index.d.ts +1 -1
  105. package/lib/solution/BookingTicket/index.d.ts +12 -3
  106. package/lib/solution/BookingTicket/index.js +103 -41
  107. package/lib/solution/BookingTicket/types.d.ts +5 -1
  108. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
  109. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +174 -42
  110. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
  111. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
  112. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +11 -3
  113. package/lib/solution/ShopDiscount/index.d.ts +2 -0
  114. package/lib/solution/ShopDiscount/index.js +55 -9
  115. package/lib/solution/ShopDiscount/utils.d.ts +4 -2
  116. package/lib/solution/ShopDiscount/utils.js +42 -25
  117. package/lib/solution/UnifiedBookingSales/index.d.ts +2 -2
  118. package/lib/solution/UnifiedBookingSales/index.js +5 -5
  119. package/lib/utils/os-private-payload.d.ts +5 -0
  120. package/lib/utils/os-private-payload.js +22 -0
  121. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
- import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
3
+ import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentOptions, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
4
4
  import { OrderModule } from '../../modules/Order';
5
5
  import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions, SalesNote, SalesNotesMutationSnapshot, SetSalesNoteInput, PickupReferenceMode, ShopServiceData, ShopServiceType } from '../../modules/Order/types';
6
6
  import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
@@ -72,6 +72,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
72
72
  private walletAssetsRefreshSequence;
73
73
  private salesDetailHydrateQueue;
74
74
  private serverOrderChangeUnsubscribe;
75
+ private paymentMethodsChangedUnsubscribe;
75
76
  private serverOrderChangeHydrateInFlight;
76
77
  private queuedServerOrderChanges;
77
78
  private serverOrderChangeSyncEnabled;
@@ -101,6 +102,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
101
102
  private drainQueuedServerOrderChanges;
102
103
  private syncCurrentSalesDetailFromServerOrderChange;
103
104
  private registerServerOrderChangeSync;
105
+ private registerPaymentMethodsChangeSync;
104
106
  private hydrateLatestLoadedSalesDetail;
105
107
  private hydrateOrderPaymentNames;
106
108
  get payment(): PaymentModule | undefined;
@@ -271,6 +273,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
271
273
  private mergeHistoricalDiscountList;
272
274
  private shouldSkipAutoApplyFetchedDiscountsInEditMode;
273
275
  private mergeCurrentDiscountSelectionState;
276
+ private resolveDiscountConfigCustomerId;
277
+ /**
278
+ * Stable across notifyTempOrderChanged's immutable object replacement, while
279
+ * still distinguishing two local orders for the same customer.
280
+ */
281
+ private getDiscountConfigOrderIdentityKey;
274
282
  loadDiscountConfig(params?: {
275
283
  customerId?: number;
276
284
  action?: 'create' | 'edit';
@@ -407,6 +415,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
407
415
  refreshWalletAssets(params?: {
408
416
  order_wait_pay_amount?: number;
409
417
  preserveSelection?: boolean;
418
+ retainSearchResultCodes?: string[];
410
419
  }): Promise<WalletAssetsState>;
411
420
  /** 选择或取消单张钱包资产,并立即同步 pending wallet payments。 */
412
421
  selectWalletAsset(params: {
@@ -442,7 +451,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
442
451
  private findCashPaymentMethod;
443
452
  private getPendingWalletPaymentAmount;
444
453
  /** 读取现金 action 所需的支付方式、待付金额和快捷金额。 */
445
- getCashPaymentConfig(): Promise<BaseSalesCashPaymentConfig>;
454
+ getCashPaymentConfig(options?: BaseSalesCashPaymentOptions): Promise<BaseSalesCashPaymentConfig>;
446
455
  /**
447
456
  * 确认足额覆盖订单的 pending Wallet 支付并提交订单。
448
457
  *
@@ -37,6 +37,7 @@ var _transformBaseProductToOrderProduct = require("./utils/transformBaseProductT
37
37
  var _quotationPrice = require("./utils/quotationPrice");
38
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
39
  const SERVER_ORDER_CHANGED_EVENT = 'order:onOrdersChanged';
40
+ const PAYMENT_METHODS_CHANGED_EVENT = 'payment:onPaymentMethodsChanged';
40
41
  const OS_FULFILLMENT_REF_MODE_FIELD = '_os_fulfillment_ref_mode';
41
42
  const OS_INVOICE_LAYOUT_CONFIG_FIELD = '_os_invoice_layout_config';
42
43
  const OS_INVOICE_TEMPLATE_SETTINGS_FIELD = '_os_invoice_template_settings';
@@ -345,6 +346,7 @@ function areBaseSalesNotesEquivalent(currentValue, loadedValue, options) {
345
346
  return currentNotes !== null && loadedNotes !== null && (0, _lodashEs.isEqual)(currentNotes, loadedNotes);
346
347
  }
347
348
  function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
349
+ const loadedHasOrderMetaList = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'order_meta_list');
348
350
  const loadedHasSalesNotes = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'notes');
349
351
  const hasDirtyLocalSalesNotes = currentTempOrder?._extend?.salesNotesState?.dirty === true;
350
352
  const incomingSalesNotesMatchLocal = loadedHasSalesNotes && areBaseSalesNotesEquivalent(currentTempOrder?.notes, loadedRecord.notes, {
@@ -363,6 +365,12 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
363
365
  });
364
366
  const uidRemaps = [];
365
367
  const mergedRecord = (0, _lodashEs.mergeWith)(normalizedCurrentTempOrder, normalizedLoadedRecord, (currentValue, loadedValue, key) => {
368
+ // order_meta_list 是服务端/本地订单携带的完整业务快照。若 incoming
369
+ // 明确提供它,必须整体替换;若省略,则保留当前值,避免 snapshot
370
+ // 数组递归拼接后出现同 ID 的旧数据。
371
+ if (key === 'order_meta_list') {
372
+ return (0, _lodashEs.cloneDeep)(loadedHasOrderMetaList ? loadedValue : currentValue);
373
+ }
366
374
  if (key === 'notes') {
367
375
  if (preserveDirtyLocalSalesNotes && Array.isArray(currentValue)) {
368
376
  return (0, _lodashEs.cloneDeep)(currentValue);
@@ -487,6 +495,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
487
495
  walletAssetsRefreshSequence = 0;
488
496
  salesDetailHydrateQueue = Promise.resolve();
489
497
  serverOrderChangeUnsubscribe = null;
498
+ paymentMethodsChangedUnsubscribe = null;
490
499
  serverOrderChangeHydrateInFlight = null;
491
500
  queuedServerOrderChanges = [];
492
501
  serverOrderChangeSyncEnabled = false;
@@ -630,6 +639,15 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
630
639
  });
631
640
  });
632
641
  }
642
+ registerPaymentMethodsChangeSync() {
643
+ this.paymentMethodsChangedUnsubscribe?.();
644
+ const effects = this.core?.effects;
645
+ if (!effects || typeof effects.on !== 'function') return;
646
+ this.paymentMethodsChangedUnsubscribe = effects.on(PAYMENT_METHODS_CHANGED_EVENT, async payload => {
647
+ if (!Array.isArray(payload?.newMethods)) return;
648
+ await this.getPaymentMethodsAsync();
649
+ });
650
+ }
633
651
  async hydrateLatestLoadedSalesDetail(record, loadSequence, options) {
634
652
  let hydratedSales = null;
635
653
  let skippedBeforeHydrate = false;
@@ -1331,9 +1349,22 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1331
1349
  }
1332
1350
  syncAppDataToTempOrder(tempOrder) {
1333
1351
  const isPriceIncludeTax = this.getAppData('is_price_include_tax');
1334
- const taxCountryCode = this.getAppData('tax_country_code');
1335
- const currencyCode = this.getAppData('shop_currency_code');
1336
- const currencySymbol = this.getAppData('shop_symbol');
1352
+ const rawTaxCountryCode = this.getAppData('tax_country_code');
1353
+ const rawCurrencyCode = this.getAppData('shop_currency_code');
1354
+ const rawCurrencySymbol = this.getAppData('shop_symbol');
1355
+ const normalizeNonBlankValue = value => {
1356
+ if (value === undefined || value === null) return undefined;
1357
+ const normalizedValue = String(value).trim();
1358
+ return normalizedValue || undefined;
1359
+ };
1360
+ const taxCountryCode = normalizeNonBlankValue(rawTaxCountryCode);
1361
+ const currencyCode = normalizeNonBlankValue(rawCurrencyCode);
1362
+ const currencySymbol = normalizeNonBlankValue(rawCurrencySymbol);
1363
+ const before = {
1364
+ tax_country_code: tempOrder.tax_country_code,
1365
+ currency_code: tempOrder.currency_code,
1366
+ currency_symbol: tempOrder.currency_symbol
1367
+ };
1337
1368
  // 历史虚拟币订单不依赖交易开关;普通 POS 不从商品行残留快照推断订单币种。
1338
1369
  const isHistoricalVirtualSettlement = this.isHistoricalVirtualSettlementOrder(tempOrder);
1339
1370
  const isVirtualSettlement = this.isActiveVirtualSettlementOrder(tempOrder) || isHistoricalVirtualSettlement;
@@ -1347,9 +1378,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1347
1378
  }
1348
1379
  }
1349
1380
  if (taxCountryCode !== undefined) {
1350
- const nextTaxCountryCode = String(taxCountryCode || '');
1351
- if (tempOrder.tax_country_code !== nextTaxCountryCode) {
1352
- tempOrder.tax_country_code = nextTaxCountryCode;
1381
+ if (tempOrder.tax_country_code !== taxCountryCode) {
1382
+ tempOrder.tax_country_code = taxCountryCode;
1353
1383
  isChanged = true;
1354
1384
  }
1355
1385
  }
@@ -1366,19 +1396,45 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1366
1396
  }
1367
1397
  }
1368
1398
  if (!isVirtualSettlement && currencyCode !== undefined) {
1369
- const nextCurrencyCode = String(currencyCode || '');
1370
- if (tempOrder.currency_code !== nextCurrencyCode) {
1371
- tempOrder.currency_code = nextCurrencyCode;
1399
+ if (tempOrder.currency_code !== currencyCode) {
1400
+ tempOrder.currency_code = currencyCode;
1372
1401
  isChanged = true;
1373
1402
  }
1374
1403
  }
1375
1404
  if (!isVirtualSettlement && currencySymbol !== undefined) {
1376
- const nextCurrencySymbol = String(currencySymbol || '');
1377
- if (tempOrder.currency_symbol !== nextCurrencySymbol) {
1378
- tempOrder.currency_symbol = nextCurrencySymbol;
1405
+ if (tempOrder.currency_symbol !== currencySymbol) {
1406
+ tempOrder.currency_symbol = currencySymbol;
1379
1407
  isChanged = true;
1380
1408
  }
1381
1409
  }
1410
+ try {
1411
+ const orderIdentity = this.store.order?.getOrderIdentity?.();
1412
+ this.logger?.addLog?.({
1413
+ type: 'info',
1414
+ title: 'syncAppDataToTempOrder',
1415
+ metadata: {
1416
+ moduleName: this.name,
1417
+ cacheId: this.cacheId,
1418
+ orderId: orderIdentity?.orderId ?? tempOrder.order_id,
1419
+ externalSaleNumber: orderIdentity?.externalSaleNumber ?? tempOrder.external_sale_number,
1420
+ shopOrderNumber: orderIdentity?.shopOrderNumber ?? tempOrder.shop_order_number,
1421
+ readValues: {
1422
+ tax_country_code: rawTaxCountryCode,
1423
+ shop_currency_code: rawCurrencyCode,
1424
+ shop_symbol: rawCurrencySymbol
1425
+ },
1426
+ before,
1427
+ after: {
1428
+ tax_country_code: tempOrder.tax_country_code,
1429
+ currency_code: tempOrder.currency_code,
1430
+ currency_symbol: tempOrder.currency_symbol
1431
+ },
1432
+ isChanged
1433
+ }
1434
+ });
1435
+ } catch {
1436
+ // 诊断日志不能影响订单字段同步。
1437
+ }
1382
1438
  return isChanged;
1383
1439
  }
1384
1440
  async initialize(core, options = {}) {
@@ -1429,12 +1485,15 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1429
1485
  this.store.order.setEnableTempOrderPersist(this.otherParams.enableTempOrderPersist);
1430
1486
  }
1431
1487
  await this.getPaymentMethodsAsync();
1488
+ this.registerPaymentMethodsChangeSync();
1432
1489
  this.registerServerOrderChangeSync();
1433
1490
  this.core.effects.emit(`${this.name}:onInited`, {});
1434
1491
  }
1435
1492
  async destroy() {
1436
1493
  this.serverOrderChangeUnsubscribe?.();
1437
1494
  this.serverOrderChangeUnsubscribe = null;
1495
+ this.paymentMethodsChangedUnsubscribe?.();
1496
+ this.paymentMethodsChangedUnsubscribe = null;
1438
1497
  Object.keys(this.store).forEach(key => {
1439
1498
  if (this.reusedSharedSubModuleNames.has(key)) return;
1440
1499
  const sub = this.store[key];
@@ -1790,7 +1849,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1790
1849
  if (!this.isPersistedOrderProduct(item)) return;
1791
1850
  (item.discount_list || []).forEach(discount => {
1792
1851
  const discountId = discount.discount?.resource_id || discount.id;
1793
- if (!discountId || !['good_pass', 'discount_card'].includes(discount.type)) return;
1852
+ if (!discountId || !['entitlement_pass', 'good_pass', 'discount_card'].includes(discount.type)) return;
1794
1853
  const quantity = item.quantity || item.num || item.product_quantity || 1;
1795
1854
  const savedAmount = new _decimal.default(discount.amount || 0).times(quantity).plus(discount?.metadata?.product_discount_difference || 0);
1796
1855
  const index = historyDiscountList.findIndex(n => n.id === discountId);
@@ -1882,19 +1941,46 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1882
1941
  return discount;
1883
1942
  });
1884
1943
  }
1944
+ resolveDiscountConfigCustomerId(tempOrder) {
1945
+ return Number(tempOrder?.customer_id || tempOrder?.customer?.id || tempOrder?._extend?.customerSnapshot?.id || tempOrder?._extend?.customerSnapshot?.customer_id || 0);
1946
+ }
1947
+
1948
+ /**
1949
+ * Stable across notifyTempOrderChanged's immutable object replacement, while
1950
+ * still distinguishing two local orders for the same customer.
1951
+ */
1952
+ getDiscountConfigOrderIdentityKey(tempOrder) {
1953
+ const identity = this.store.order?.getOrderIdentity?.();
1954
+ return JSON.stringify([identity?.orderId ?? tempOrder?.order_id ?? '', tempOrder?.request_unique_idempotency_token ?? '', identity?.externalSaleNumber ?? tempOrder?.external_sale_number ?? '', identity?.localId ?? tempOrder?._extend?.localId ?? this.cacheId ?? '']);
1955
+ }
1885
1956
  async loadDiscountConfig(params) {
1886
1957
  if (!this.store.order) throw new Error('order 模块未初始化');
1887
1958
  const tempOrder = this.store.order.ensureTempOrder();
1888
1959
  const orderStore = this.store.order.store || {};
1889
1960
  const discountModule = orderStore.discount;
1890
1961
  const rulesModule = orderStore.rules;
1891
- const orderId = tempOrder.order_id || this.getOrderIdentity?.()?.orderId;
1962
+ const orderId = tempOrder.order_id || this.store.order.getOrderIdentity?.()?.orderId;
1892
1963
  const customerId = Number(params?.customerId || tempOrder.customer_id || tempOrder.customer?.id || tempOrder._extend?.customerSnapshot?.id || tempOrder._extend?.customerSnapshot?.customer_id || 0);
1893
1964
  const currentDiscountList = discountModule?.getDiscountList?.() || [];
1894
1965
  const originalDiscountList = discountModule?.getOriginalDiscountList?.() || [];
1895
1966
  const hasManualDiscountSelection = this.hasManualDiscountSelection || currentDiscountList.some(discount => discount.isManualSelect);
1896
1967
  const discountAction = params?.action || (orderId ? 'edit' : 'create');
1897
- const discountConfigCacheKey = [customerId, discountAction, Number(orderId) || 0].join(':');
1968
+ const requestOrderIdentityKey = this.getDiscountConfigOrderIdentityKey(tempOrder);
1969
+ const discountConfigCacheKey = JSON.stringify([customerId, discountAction, Number(orderId) || 0, requestOrderIdentityKey]);
1970
+ let requestEpoch = this.store.order.getCustomerWalletPrepareConfigEpoch?.();
1971
+ const isCurrentRequest = () => {
1972
+ const currentTempOrder = this.store.order?.getTempOrder?.();
1973
+ return Boolean(currentTempOrder && (requestEpoch === undefined || this.store.order?.getCustomerWalletPrepareConfigEpoch?.() === requestEpoch) && this.resolveDiscountConfigCustomerId(currentTempOrder) === customerId && this.getDiscountConfigOrderIdentityKey(currentTempOrder) === requestOrderIdentityKey);
1974
+ };
1975
+ const getCurrentResult = () => {
1976
+ const currentTempOrder = this.store.order?.getTempOrder?.();
1977
+ return {
1978
+ productList: currentTempOrder?.products || [],
1979
+ discountList: discountModule?.getDiscountList?.() || [],
1980
+ availableWalletIds: this.getAvailableWalletIds(),
1981
+ virtualCurrencyList: this.getVirtualCurrencyList()
1982
+ };
1983
+ };
1898
1984
 
1899
1985
  // Walk-In 不请求 prepare config;当前搜索/扫码券必须继续参与本次重算。
1900
1986
  // current 优先于 original,保留搜索后的最新选择与可用状态。
@@ -1905,26 +1991,34 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1905
1991
  if (!params?.force && this.discountConfigCacheKey === discountConfigCacheKey) {
1906
1992
  preparedDiscountList = originalDiscountList;
1907
1993
  } else {
1908
- preparedDiscountList = await this.store.order.loadDiscountConfig({
1994
+ const prepareConfigPromise = this.store.order.loadDiscountConfig({
1909
1995
  customerId,
1910
1996
  action: discountAction,
1911
1997
  orderId: Number(orderId) || undefined,
1912
1998
  apply: false
1913
1999
  });
1914
- this.discountConfigCacheKey = discountConfigCacheKey;
2000
+ // OrderModule increments this epoch synchronously before its first await.
2001
+ requestEpoch = this.store.order.getCustomerWalletPrepareConfigEpoch?.();
2002
+ preparedDiscountList = await prepareConfigPromise;
2003
+ if (!isCurrentRequest()) return getCurrentResult();
1915
2004
  await discountModule?.setOriginalDiscountList?.(preparedDiscountList);
2005
+ if (!isCurrentRequest()) return getCurrentResult();
2006
+ this.discountConfigCacheKey = discountConfigCacheKey;
1916
2007
  }
1917
2008
  }
1918
2009
  if (this.isActiveVirtualSettlementOrder(tempOrder)) {
2010
+ if (!isCurrentRequest()) return getCurrentResult();
1919
2011
  await discountModule?.setOriginalDiscountList?.([]);
2012
+ if (!isCurrentRequest()) return getCurrentResult();
1920
2013
  await discountModule?.setDiscountList?.([]);
2014
+ if (!isCurrentRequest()) return getCurrentResult();
1921
2015
  tempOrder.discount_list = [];
1922
2016
  tempOrder.shop_discount = '0.00';
1923
2017
  return {
1924
2018
  productList: tempOrder.products || [],
1925
2019
  discountList: [],
1926
2020
  availableWalletIds: this.getAvailableWalletIds(),
1927
- virtualCurrencyList: this.store.order.getVirtualCurrencyList()
2021
+ virtualCurrencyList: this.getVirtualCurrencyList()
1928
2022
  };
1929
2023
  }
1930
2024
  if (hasManualDiscountSelection && currentDiscountList.length) {
@@ -1932,12 +2026,14 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1932
2026
  productList: tempOrder.products || [],
1933
2027
  discountList: currentDiscountList,
1934
2028
  availableWalletIds: this.getAvailableWalletIds(),
1935
- virtualCurrencyList: this.store.order.getVirtualCurrencyList()
2029
+ virtualCurrencyList: this.getVirtualCurrencyList()
1936
2030
  };
1937
2031
  }
1938
2032
  let nextDiscountList = this.mergeHistoricalDiscountList(preparedDiscountList || discountModule?.getDiscountList?.() || [], tempOrder.products || []);
1939
2033
  nextDiscountList = this.mergeCurrentDiscountSelectionState(nextDiscountList, currentDiscountList);
2034
+ if (!isCurrentRequest()) return getCurrentResult();
1940
2035
  await discountModule?.setDiscountList(nextDiscountList);
2036
+ if (!isCurrentRequest()) return getCurrentResult();
1941
2037
  const shouldSkipAutoApplyFetchedDiscounts = this.shouldSkipAutoApplyFetchedDiscountsInEditMode({
1942
2038
  discountAction,
1943
2039
  products: tempOrder.products || [],
@@ -1945,24 +2041,28 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1945
2041
  nextDiscountList
1946
2042
  });
1947
2043
  if (shouldSkipAutoApplyFetchedDiscounts) {
1948
- const summary = await this.store.order.recalculateSummary({
2044
+ await this.store.order.recalculateSummary({
1949
2045
  createIfMissing: true
1950
2046
  });
2047
+ if (!isCurrentRequest()) return getCurrentResult();
1951
2048
  this.store.order.persistTempOrder();
2049
+ if (!isCurrentRequest()) return getCurrentResult();
1952
2050
  await this.effectsEmit('onDiscountApplied', {
1953
2051
  productList: tempOrder.products || [],
1954
2052
  discountList: nextDiscountList,
1955
2053
  selectedDiscountList: tempOrder.discount_list || [],
1956
2054
  tempOrder
1957
2055
  });
2056
+ if (!isCurrentRequest()) return getCurrentResult();
1958
2057
  return {
1959
2058
  productList: tempOrder.products || [],
1960
2059
  discountList: nextDiscountList,
1961
2060
  availableWalletIds: this.getAvailableWalletIds(),
1962
- virtualCurrencyList: this.store.order.getVirtualCurrencyList()
2061
+ virtualCurrencyList: this.getVirtualCurrencyList()
1963
2062
  };
1964
2063
  }
1965
2064
  if (rulesModule) {
2065
+ if (!isCurrentRequest()) return getCurrentResult();
1966
2066
  const orderTotalAmount = Number(orderStore.summary?.total_amount || 0);
1967
2067
  const result = rulesModule.calcDiscount({
1968
2068
  productList: tempOrder.products,
@@ -1998,25 +2098,31 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
1998
2098
  if (result.discountList) {
1999
2099
  nextDiscountList = this.mergeHistoricalDiscountList(result.discountList, tempOrder.products || []);
2000
2100
  _Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
2101
+ if (!isCurrentRequest()) return getCurrentResult();
2001
2102
  await discountModule?.setDiscountList(nextDiscountList);
2103
+ if (!isCurrentRequest()) return getCurrentResult();
2002
2104
  tempOrder.discount_list = nextDiscountList.filter(discount => discount.isSelected);
2003
2105
  }
2004
2106
  }
2005
- const summary = await this.store.order.recalculateSummary({
2107
+ if (!isCurrentRequest()) return getCurrentResult();
2108
+ await this.store.order.recalculateSummary({
2006
2109
  createIfMissing: true
2007
2110
  });
2111
+ if (!isCurrentRequest()) return getCurrentResult();
2008
2112
  this.store.order.persistTempOrder();
2113
+ if (!isCurrentRequest()) return getCurrentResult();
2009
2114
  await this.effectsEmit('onDiscountApplied', {
2010
2115
  productList: tempOrder.products || [],
2011
2116
  discountList: nextDiscountList,
2012
2117
  selectedDiscountList: tempOrder.discount_list || [],
2013
2118
  tempOrder
2014
2119
  });
2120
+ if (!isCurrentRequest()) return getCurrentResult();
2015
2121
  return {
2016
2122
  productList: tempOrder.products || [],
2017
2123
  discountList: nextDiscountList,
2018
2124
  availableWalletIds: this.getAvailableWalletIds(),
2019
- virtualCurrencyList: this.store.order.getVirtualCurrencyList()
2125
+ virtualCurrencyList: this.getVirtualCurrencyList()
2020
2126
  };
2021
2127
  }
2022
2128
  getAvailableWalletIds() {
@@ -2057,6 +2163,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
2057
2163
  holders: [],
2058
2164
  isFormSubject: product => (0, _utils.resolveIsFormSubject)(tempOrder, product),
2059
2165
  orderTotalAmount
2166
+ }, {
2167
+ preserveEntitlementSelection: false
2060
2168
  }) || result;
2061
2169
  if (result.productList) {
2062
2170
  tempOrder.products = preserveManualProductDiscountProducts(tempOrder.products, result.productList);
@@ -2972,6 +3080,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
2972
3080
  };
2973
3081
  }
2974
3082
  const result = await this.store.payment.wallet.initializeWalletDataFromBusinessAsync(walletBusinessData);
3083
+ this.store.order.mergePointCardSnapshotCodes?.(result.userIdentificationCodes, {
3084
+ customerId: walletBusinessData.customer_id,
3085
+ orderIdentity: snapshot?.identity
3086
+ });
2975
3087
  await this.core.effects.emit(`${this.name}:onWalletDataInitialized`, {
2976
3088
  orderId: snapshot?.identity?.orderId,
2977
3089
  customerId: walletBusinessData.customer_id,
@@ -3098,6 +3210,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3098
3210
  async importWalletAssetsSnapshot(snapshot) {
3099
3211
  if (!this.store.payment) throw new Error('payment 模块未初始化');
3100
3212
  const state = this.store.payment.wallet.importWalletAssetsSnapshot(snapshot);
3213
+ this.store.order?.mergePointCardSnapshotCodes?.(state.items);
3101
3214
  await this.syncSelectedWalletAssets(state);
3102
3215
  return this.publishWalletAssetsState(state);
3103
3216
  }
@@ -3119,6 +3232,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3119
3232
  });
3120
3233
  return this.publishWalletAssetsState(emptyState);
3121
3234
  }
3235
+ const pointCardSnapshotMergeContext = {
3236
+ customerId: businessData.customer_id,
3237
+ orderIdentity: this.store.order.getOrderSnapshot()?.identity
3238
+ };
3122
3239
  const previousState = wallet.getWalletAssetsState();
3123
3240
  const hasPreviousWalletContext = previousState.status !== 'idle' || previousState.items.length > 0 || previousState.selectedIds.length > 0 || previousState.customerId !== undefined;
3124
3241
  const customerChanged = hasPreviousWalletContext && String(previousState.customerId ?? '') !== String(businessData.customer_id ?? '');
@@ -3130,7 +3247,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3130
3247
  await this.publishWalletAssetsState(clearedState);
3131
3248
  }
3132
3249
  const refreshTask = wallet.refreshWalletAssetsFromBusinessAsync(businessData, {
3133
- preserveSelection: params?.preserveSelection !== false && !customerChanged
3250
+ preserveSelection: params?.preserveSelection !== false && !customerChanged,
3251
+ retainSearchResultCodes: params?.retainSearchResultCodes
3134
3252
  });
3135
3253
  await this.publishWalletAssetsState(wallet.getWalletAssetsState());
3136
3254
  let state = await refreshTask;
@@ -3140,6 +3258,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3140
3258
  if (state.status !== 'error') {
3141
3259
  const committed = this.getCommittedWalletAssets();
3142
3260
  state = wallet.setCommittedWalletAssets(committed.ids, committed.assets);
3261
+ this.store.order.mergePointCardSnapshotCodes?.(wallet.getUserIdentificationCodes?.() || [], pointCardSnapshotMergeContext);
3143
3262
  }
3144
3263
  await this.syncSelectedWalletAssets(state);
3145
3264
  return this.publishWalletAssetsState(state);
@@ -3197,7 +3316,13 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3197
3316
  */
3198
3317
  updateOrderCustomer(customer) {
3199
3318
  if (!this.store.order) throw new Error('order 模块未初始化');
3319
+ const previousCustomerId = this.resolveDiscountConfigCustomerId(this.store.order.getTempOrder?.());
3200
3320
  const result = this.store.order.updateTempOrderCustomer(customer);
3321
+ const nextCustomerId = this.resolveDiscountConfigCustomerId(this.store.order.getTempOrder?.());
3322
+ if (String(previousCustomerId) !== String(nextCustomerId)) {
3323
+ this.discountConfigCacheKey = null;
3324
+ this.hasManualDiscountSelection = false;
3325
+ }
3201
3326
  this.store.order.recalculateSummary({
3202
3327
  createIfMissing: true
3203
3328
  });
@@ -3231,10 +3356,14 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3231
3356
  getPaymentMethods() {
3232
3357
  return [...this.paymentMethodsCache];
3233
3358
  }
3234
- findCashPaymentMethod(paymentMethods) {
3359
+ findCashPaymentMethod(paymentMethods, paymentMethodId) {
3235
3360
  return paymentMethods.find(method => {
3361
+ if (method?.enabled === false || method?.enable === false) return false;
3236
3362
  const identifiers = [method?.code, method?.type, method?.tag].map(value => String(value || '').toUpperCase());
3237
- return identifiers.includes('CASHMANUAL') && method?.enabled !== false && method?.enable !== false;
3363
+ const isDefaultCash = identifiers.includes('CASHMANUAL');
3364
+ if (paymentMethodId === undefined) return isDefaultCash;
3365
+ const isCustomCash = String(method?.type || '').trim().toLowerCase() === 'custom' && [method?.name, method?.nameEn].some(name => typeof name === 'string' && /现金|現金|cash/i.test(name));
3366
+ return String(method?.id) === String(paymentMethodId) && (isDefaultCash || isCustomCash);
3238
3367
  });
3239
3368
  }
3240
3369
  getPendingWalletPaymentAmount(payments = this.store.order?.getOrderPayments?.() || []) {
@@ -3251,13 +3380,16 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3251
3380
  }
3252
3381
 
3253
3382
  /** 读取现金 action 所需的支付方式、待付金额和快捷金额。 */
3254
- async getCashPaymentConfig() {
3383
+ async getCashPaymentConfig(options = {}) {
3255
3384
  if (!this.store.payment) throw new Error('payment 模块未初始化');
3256
3385
  let paymentMethods = this.getPaymentMethods();
3257
- let paymentMethod = this.findCashPaymentMethod(paymentMethods);
3386
+ let paymentMethod = this.findCashPaymentMethod(paymentMethods, options.paymentMethodId);
3258
3387
  if (!paymentMethod) {
3259
3388
  paymentMethods = await this.getPaymentMethodsAsync();
3260
- paymentMethod = this.findCashPaymentMethod(paymentMethods);
3389
+ paymentMethod = this.findCashPaymentMethod(paymentMethods, options.paymentMethodId);
3390
+ }
3391
+ if (!paymentMethod && options.paymentMethodId !== undefined) {
3392
+ throw new Error(`未找到可用的现金支付方式:${options.paymentMethodId}`);
3261
3393
  }
3262
3394
  const amountSnapshot = this.store.order?.getOrderAmountSnapshot?.();
3263
3395
  const pendingWalletAmount = this.getPendingWalletPaymentAmount();
@@ -3355,7 +3487,9 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
3355
3487
  if (!Number.isFinite(amount) || amount <= 0) {
3356
3488
  throw new Error('现金支付金额必须大于 0');
3357
3489
  }
3358
- const config = await this.getCashPaymentConfig();
3490
+ const config = params.paymentMethodId === undefined ? await this.getCashPaymentConfig() : await this.getCashPaymentConfig({
3491
+ paymentMethodId: params.paymentMethodId
3492
+ });
3359
3493
  const paymentMethod = config.paymentMethod;
3360
3494
  if (!paymentMethod) throw new Error('未找到可用的 CASHMANUAL 支付方式');
3361
3495
  if (config.amountDue <= 0) throw new Error('当前订单没有待支付金额');
@@ -23,13 +23,17 @@ export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSales
23
23
  export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
24
24
  export type BaseSalesStatus = 'idle' | 'initializing' | 'ready' | 'error';
25
25
  export type BaseSalesPaymentStatus = 'paid' | 'partially_paid' | 'unpaid' | 'payment_processing' | string;
26
+ export interface BaseSalesCashPaymentOptions {
27
+ /** 指定现金支付方式;省略时使用默认 CASHMANUAL。 */
28
+ paymentMethodId?: number | string;
29
+ }
26
30
  export interface BaseSalesCashPaymentConfig {
27
31
  available: boolean;
28
32
  paymentMethod?: PaymentMethod;
29
33
  amountDue: number;
30
34
  recommendedAmounts: number[];
31
35
  }
32
- export interface BaseSalesPayCashParams {
36
+ export interface BaseSalesPayCashParams extends BaseSalesCashPaymentOptions {
33
37
  /** 实际计入订单的现金支付金额(部分支付时小于待付金额)。 */
34
38
  amount: number;
35
39
  /** 顾客实际交付现金;可大于 amount。 */
@@ -441,10 +445,10 @@ export interface BaseSalesAddLogParams extends BaseSalesLogInput {
441
445
  /** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList 或 scannedDiscountList 补 Holder) */
442
446
  export interface BaseSalesScanCodeResult {
443
447
  isAvailable: boolean;
444
- /** 卡券已加入 Promotion;false 时可能是无效、过期或已使用。 */
448
+ /** 卡券已加入 Promotion;可能因次数、时间或当前订单条件而暂时无法应用。 */
445
449
  isAccepted?: boolean;
446
450
  type?: 'server' | string;
447
451
  unavailableReason?: 'time_limit' | string;
448
- /** batchSearch 原始结果;Holder 补全等流程可从这里读取原始卡券。 */
452
+ /** 扫码卡券资料及最新可用状态,供 Holder 补全等流程使用。 */
449
453
  scannedDiscountList?: Discount[];
450
454
  }
@@ -17,6 +17,7 @@ exports.resolveStrategyEligibleProducts = resolveStrategyEligibleProducts;
17
17
  exports.resolveStrategyRequiredQuantity = resolveStrategyRequiredQuantity;
18
18
  var _decimal = _interopRequireDefault(require("decimal.js"));
19
19
  var _lodashEs = require("lodash-es");
20
+ var _entitlementPass = require("../../../modules/Discount/entitlementPass");
20
21
  var _utils = require("../../../modules/Order/utils");
21
22
  var _utils2 = require("../../ScanOrder/utils");
22
23
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -395,11 +396,16 @@ function getProductLineNoteSignature(product) {
395
396
  const uid = getOrderProductUid(product);
396
397
  return uid ? `note:${uid}` : `note:${normalizedNote}`;
397
398
  }
398
- function hasGoodPassDiscount(product) {
399
+ function getFullCoveragePassDiscountType(product) {
399
400
  const productBundle = Array.isArray(product?.product_bundle) ? product.product_bundle : [];
400
401
  const extendedBundle = Array.isArray(product?._extend?.other?.bundle) ? product._extend.other.bundle : [];
401
402
  const discountLists = [product?.discount_list, ...productBundle.map(item => item?.discount_list), ...extendedBundle.map(item => item?.discount_list)];
402
- return discountLists.some(discountList => Array.isArray(discountList) && discountList.some(item => item?.type === 'good_pass' || item?.tag === 'good_pass'));
403
+ for (const discountList of discountLists) {
404
+ if (!Array.isArray(discountList)) continue;
405
+ const pass = discountList.find(item => (0, _entitlementPass.isFullCoveragePass)(item));
406
+ if (pass) return String(pass.type || pass.tag);
407
+ }
408
+ return null;
403
409
  }
404
410
 
405
411
  /**
@@ -412,8 +418,10 @@ function getPromotionLineMergeBoundary(product) {
412
418
  if (product?.product_id === undefined || product?.product_id === null) {
413
419
  return `custom:${getOrderProductUid(product)}`;
414
420
  }
415
- if (hasGoodPassDiscount(product)) {
416
- return `good-pass:${getOrderProductUid(product)}`;
421
+ const fullCoveragePassType = getFullCoveragePassDiscountType(product);
422
+ if (fullCoveragePassType) {
423
+ const boundary = fullCoveragePassType === 'good_pass' ? 'good-pass' : 'entitlement-pass';
424
+ return `${boundary}:${getOrderProductUid(product)}`;
417
425
  }
418
426
  if (Number(product?.product_sku?.open_sold_weight || 0) === 1) {
419
427
  return `weighing:${getOrderProductUid(product)}`;
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
329
+ weekNum: 0 | 2 | 1 | 6 | 4 | 5 | 3;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -8,6 +8,7 @@ import { BaseSalesImpl } from '../BaseSales';
8
8
  import type { BaseSalesScanCodeResult } from '../BaseSales/types';
9
9
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
10
10
  import type { LoadSalesDetailParams } from '../../modules/Order/types';
11
+ import type { GlobalScanSearchType } from './utils/scan/formatGlobalScan';
11
12
  import type { AddAddTimeProductToBookingInput, AddAddTimeProductsToBookingInput, GlobalScanHandleResult, GlobalScanHostBridge } from './types';
12
13
  import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
13
14
  import { type BuildCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildCacheItemFromOrderLine';
@@ -29,7 +30,9 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
29
30
  private addTimeProductsCatalog;
30
31
  private orderCustomerDiscountRefreshInFlight;
31
32
  private orderCustomerDiscountRefreshCustomerId;
33
+ private orderCustomerDiscountRefreshTarget;
32
34
  private orderCustomerPromotionRefreshInFlight;
35
+ private readonly customerResolveRequests;
33
36
  protected loadOpenDataInFlight: Promise<OpenDataConfig> | null;
34
37
  protected loadOpenDataInFlightTarget: string | null;
35
38
  protected openDataTarget: string | null;
@@ -45,6 +48,12 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
45
48
  */
46
49
  protected createSubModule(moduleName: string): Module | null;
47
50
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
51
+ private getInjectedOpenDataConfig;
52
+ /**
53
+ * 在解决方案对外 ready 前准备 Invoice Document;失败只降级模板,不阻断销售。
54
+ * 已由页面取得的 OpenData 直接交给模块接管,没有注入数据时再走 target-scoped 加载。
55
+ */
56
+ private prepareInvoiceTemplateAtSolutionReady;
48
57
  protected getBookingTicketBusinessCode(): string | null;
49
58
  private getIdGeneratorPlugin;
50
59
  private loadOpenDataConfig;
@@ -72,10 +81,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
72
81
  resolveCustomerById(customerId: string | number): Promise<ICustomer | null>;
73
82
  /** 兼容既有优惠码扫码逻辑。 */
74
83
  private resolveCustomerByDiscountCustomerId;
75
- private findCustomerById;
76
84
  private normalizeCustomer;
77
85
  private getRawCustomerId;
78
- private hasUsableCustomerDetails;
79
86
  /**
80
87
  * 更新当前预约的 appointment_status。
81
88
  *
@@ -339,7 +346,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
339
346
  * 获取当前的客户搜索条件
340
347
  * @returns 当前搜索条件
341
348
  */
342
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
349
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
343
350
  /**
344
351
  * 获取客户列表状态(包含滚动加载相关状态)
345
352
  * @returns 客户状态
@@ -531,6 +538,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
531
538
  * ```
532
539
  */
533
540
  handleGlobalScanCode(code: string, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;
541
+ /** 查询码类型;复用原有识别和缓存,不写订单、不打开选择 UI。 */
542
+ getGlobalScanCodeType(code: string): Promise<GlobalScanSearchType | null>;
534
543
  resolveBestAddTimePlan(addTimeProducts: any[], targetMinutes: number): any;
535
544
  /**
536
545
  * 构造一条绑定到已有 booking 的加时商品行。