@pisell/pisellos 0.10.43 → 0.10.44

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 (87) hide show
  1. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  2. package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
  3. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  4. package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
  5. package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
  6. package/dist/model/strategy/adapter/itemRule/type.js +19 -1
  7. package/dist/modules/Order/index.d.ts +41 -9
  8. package/dist/modules/Order/index.js +1438 -878
  9. package/dist/modules/Order/salesNotes.d.ts +31 -0
  10. package/dist/modules/Order/salesNotes.js +492 -0
  11. package/dist/modules/Order/types.d.ts +105 -8
  12. package/dist/modules/Order/types.js +6 -1
  13. package/dist/modules/Order/utils.d.ts +3 -1
  14. package/dist/modules/Order/utils.js +191 -71
  15. package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
  16. package/dist/modules/Payment/cashRecommendationAlgorithm.js +17 -367
  17. package/dist/modules/ProductList/index.d.ts +2 -1
  18. package/dist/modules/ProductList/index.js +100 -20
  19. package/dist/modules/ProductList/types.d.ts +10 -0
  20. package/dist/server/index.d.ts +7 -0
  21. package/dist/server/index.js +45 -3
  22. package/dist/server/modules/order/index.js +6 -0
  23. package/dist/server/modules/order/types.d.ts +9 -0
  24. package/dist/server/utils/small-ticket.d.ts +1 -0
  25. package/dist/server/utils/small-ticket.js +142 -14
  26. package/dist/solution/BaseSales/index.d.ts +15 -1
  27. package/dist/solution/BaseSales/index.js +1240 -877
  28. package/dist/solution/BookingByStep/index.d.ts +1 -1
  29. package/dist/solution/BookingTicket/index.d.ts +1 -0
  30. package/dist/solution/BookingTicket/index.js +37 -16
  31. package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
  32. package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
  33. package/dist/solution/RegisterAndLogin/config.js +95 -40
  34. package/dist/solution/RegisterAndLogin/index.js +4 -1
  35. package/dist/solution/ScanOrder/index.d.ts +1 -0
  36. package/dist/solution/ScanOrder/index.js +31 -27
  37. package/dist/solution/ScanOrder/utils.d.ts +1 -0
  38. package/dist/solution/ScanOrder/utils.js +2 -0
  39. package/dist/solution/UnifiedBookingSales/index.d.ts +15 -2
  40. package/dist/solution/UnifiedBookingSales/index.js +777 -510
  41. package/dist/solution/UnifiedBookingSales/types.d.ts +14 -1
  42. package/dist/solution/VenueBooking/index.d.ts +1 -0
  43. package/dist/solution/VenueBooking/index.js +8 -4
  44. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  45. package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
  46. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  47. package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
  48. package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
  49. package/lib/model/strategy/adapter/itemRule/type.js +19 -1
  50. package/lib/modules/Order/index.d.ts +41 -9
  51. package/lib/modules/Order/index.js +434 -61
  52. package/lib/modules/Order/salesNotes.d.ts +31 -0
  53. package/lib/modules/Order/salesNotes.js +382 -0
  54. package/lib/modules/Order/types.d.ts +105 -8
  55. package/lib/modules/Order/types.js +5 -1
  56. package/lib/modules/Order/utils.d.ts +3 -1
  57. package/lib/modules/Order/utils.js +114 -1
  58. package/lib/modules/Payment/cashRecommendationAlgorithm.d.ts +4 -5
  59. package/lib/modules/Payment/cashRecommendationAlgorithm.js +9 -354
  60. package/lib/modules/ProductList/index.d.ts +2 -1
  61. package/lib/modules/ProductList/index.js +47 -2
  62. package/lib/modules/ProductList/types.d.ts +10 -0
  63. package/lib/server/index.d.ts +7 -0
  64. package/lib/server/index.js +39 -3
  65. package/lib/server/modules/order/index.js +6 -0
  66. package/lib/server/modules/order/types.d.ts +9 -0
  67. package/lib/server/utils/small-ticket.d.ts +1 -0
  68. package/lib/server/utils/small-ticket.js +136 -12
  69. package/lib/solution/BaseSales/index.d.ts +15 -1
  70. package/lib/solution/BaseSales/index.js +192 -22
  71. package/lib/solution/BookingByStep/index.d.ts +1 -1
  72. package/lib/solution/BookingTicket/index.d.ts +1 -0
  73. package/lib/solution/BookingTicket/index.js +23 -5
  74. package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
  75. package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
  76. package/lib/solution/RegisterAndLogin/config.js +49 -8
  77. package/lib/solution/RegisterAndLogin/index.js +4 -1
  78. package/lib/solution/ScanOrder/index.d.ts +1 -0
  79. package/lib/solution/ScanOrder/index.js +5 -1
  80. package/lib/solution/ScanOrder/utils.d.ts +1 -0
  81. package/lib/solution/ScanOrder/utils.js +1 -0
  82. package/lib/solution/UnifiedBookingSales/index.d.ts +15 -2
  83. package/lib/solution/UnifiedBookingSales/index.js +125 -1
  84. package/lib/solution/UnifiedBookingSales/types.d.ts +14 -1
  85. package/lib/solution/VenueBooking/index.d.ts +1 -0
  86. package/lib/solution/VenueBooking/index.js +5 -1
  87. package/package.json +1 -1
@@ -43,6 +43,7 @@ import { filterBookingsFromOrders, sortBookings } from "./modules/order/utils/fi
43
43
  import { buildSmallTicketData, hasSmallTicketData } from "./utils/small-ticket";
44
44
  import { BaseSalesImpl } from "../solution/BaseSales";
45
45
  import { getOrderPaymentIdentityKeys, isIdentifiedPendingOrderPayment, isPendingOrderPayment, mergeOrderPaymentListsByIdentity } from "../modules/Order/payment-utils";
46
+ import { finalizeSalesNotesForCheckout } from "../modules/Order/salesNotes";
46
47
  import { normalizeOrderCollections } from "../modules/Order/utils/orderCollectionIdentity";
47
48
  import { stripOsPrivatePayloadFields } from "../utils/os-private-payload";
48
49
  import { getDefaultInvoiceLayoutConfig, getDefaultInvoiceTemplateSettings, normalizeRawInvoiceTemplateSettings, resolveInvoiceReceiptLocales } from "../modules/OpenData";
@@ -4369,12 +4370,14 @@ var Server = /*#__PURE__*/function () {
4369
4370
 
4370
4371
  /**
4371
4372
  * 预约查询是否走本地:
4373
+ * - 日历周/月/资源视图通过 compact_fields 显式标识,始终走远端;
4372
4374
  * - 当 sales_time_between 的开始和结束都不是今天时,走远端;
4373
4375
  * - 其余情况走本地。
4374
4376
  */
4375
4377
  }, {
4376
4378
  key: "shouldUseLocalBookingQuery",
4377
4379
  value: function shouldUseLocalBookingQuery(data) {
4380
+ if ((data === null || data === void 0 ? void 0 : data.compact_fields) === true) return false;
4378
4381
  var range = data === null || data === void 0 ? void 0 : data.sales_time_between;
4379
4382
  if (!Array.isArray(range) || range.length < 2) return true;
4380
4383
  return !this.isRangeBothNotToday(range[0], range[1]);
@@ -5868,7 +5871,7 @@ var Server = /*#__PURE__*/function () {
5868
5871
  _context57.next = 7;
5869
5872
  break;
5870
5873
  }
5871
- return _context57.abrupt("return", next);
5874
+ return _context57.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5872
5875
  case 7:
5873
5876
  idGenerator = this.getIdGeneratorPlugin();
5874
5877
  if (idGenerator) {
@@ -5879,7 +5882,7 @@ var Server = /*#__PURE__*/function () {
5879
5882
  needsShopOrderNumber: needsShopOrderNumber,
5880
5883
  needsShopFullOrderNumber: needsShopFullOrderNumber
5881
5884
  });
5882
- return _context57.abrupt("return", next);
5885
+ return _context57.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5883
5886
  case 11:
5884
5887
  _context57.prev = 11;
5885
5888
  if (!(needsShopOrderNumber && idGenerator.generateShopOrderNumber)) {
@@ -5917,7 +5920,7 @@ var Server = /*#__PURE__*/function () {
5917
5920
  error: _context57.t0 instanceof Error ? _context57.t0.message : String(_context57.t0)
5918
5921
  });
5919
5922
  case 26:
5920
- return _context57.abrupt("return", next);
5923
+ return _context57.abrupt("return", this.finalizeCheckoutSalesNotes(next, title));
5921
5924
  case 27:
5922
5925
  case "end":
5923
5926
  return _context57.stop();
@@ -5929,6 +5932,45 @@ var Server = /*#__PURE__*/function () {
5929
5932
  }
5930
5933
  return ensureCheckoutOrderNumbers;
5931
5934
  }()
5935
+ /**
5936
+ * Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
5937
+ * shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
5938
+ * 都使用同一份完整快照。
5939
+ */
5940
+ }, {
5941
+ key: "finalizeCheckoutSalesNotes",
5942
+ value: function finalizeCheckoutSalesNotes(data, title) {
5943
+ var _data$shop_order_numb;
5944
+ if (!data || _typeof(data) !== 'object') return data;
5945
+ if (!Object.prototype.hasOwnProperty.call(data, 'notes')) return data;
5946
+ if (data.notes === undefined || data.notes === null) return data;
5947
+ if (!Array.isArray(data.notes)) {
5948
+ throw new Error('[Order Notes] checkout notes 必须为数组');
5949
+ }
5950
+ if (data.notes.length === 0) return data;
5951
+ var productTargetUuids = (Array.isArray(data.products) ? data.products : []).map(function (product) {
5952
+ var _product$metadata$uni, _product$metadata;
5953
+ return (_product$metadata$uni = product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata.unique_identification_number) !== null && _product$metadata$uni !== void 0 ? _product$metadata$uni : product === null || product === void 0 ? void 0 : product.unique_identification_number;
5954
+ }).filter(function (targetUuid) {
5955
+ return targetUuid !== undefined && targetUuid !== null && String(targetUuid).trim().length > 0;
5956
+ }).map(function (targetUuid) {
5957
+ return String(targetUuid);
5958
+ });
5959
+ var shopOrderNumber = String((_data$shop_order_numb = data.shop_order_number) !== null && _data$shop_order_numb !== void 0 ? _data$shop_order_numb : '').trim();
5960
+ var notes = finalizeSalesNotesForCheckout({
5961
+ notes: data.notes,
5962
+ shopOrderNumber: shopOrderNumber,
5963
+ productTargetUuids: productTargetUuids
5964
+ });
5965
+ this.logInfo("".concat(title, ": checkout Notes \u5DF2\u7ED1\u5B9A\u8BA2\u5355\u53F7"), {
5966
+ shop_order_number: shopOrderNumber,
5967
+ note_count: notes.length
5968
+ });
5969
+ return _objectSpread(_objectSpread({}, data), {}, {
5970
+ shop_order_number: shopOrderNumber,
5971
+ notes: notes
5972
+ });
5973
+ }
5932
5974
  }, {
5933
5975
  key: "dispatchCheckoutSyncTask",
5934
5976
  value: function () {
@@ -3249,6 +3249,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3249
3249
  mergedRecord[_field] = cloneDeep(incomingRecord[_field]);
3250
3250
  }
3251
3251
 
3252
+ // order_meta_list 是一次性生成的完整业务快照。incoming 明确携带时
3253
+ // 必须整体覆盖(包括 null / 空对象 / 空数组);省略时才保留 existing。
3254
+ if (Object.prototype.hasOwnProperty.call(incomingRecord, 'order_meta_list')) {
3255
+ mergedRecord.order_meta_list = cloneDeep(incomingRecord.order_meta_list);
3256
+ }
3257
+
3252
3258
  // 子项数组遵循完整快照语义:incoming 自有且为数组(包括 [])时权威替换;
3253
3259
  // 字段缺席或不是数组时视为稀疏 patch,继续保留 existing。
3254
3260
  for (var _i6 = 0, _ORDER_AUTHORITATIVE_2 = ORDER_AUTHORITATIVE_COLLECTION_FIELDS; _i6 < _ORDER_AUTHORITATIVE_2.length; _i6++) {
@@ -456,6 +456,15 @@ export interface OrderData {
456
456
  par_value: string;
457
457
  used_par_value: string;
458
458
  }>;
459
+ virtual_currency_snapshot?: Array<{
460
+ id: number | string;
461
+ tag: 'virtual_currency';
462
+ product_id?: number | string;
463
+ product_name: string;
464
+ par_value: string;
465
+ used_par_value: string;
466
+ name: Record<string, string>;
467
+ }>;
459
468
  };
460
469
  /**
461
470
  * 金额汇总(仅输出)。
@@ -45,6 +45,7 @@ export interface SmallTicketProduct {
45
45
  product_uid?: string | number;
46
46
  booking_uid?: string | number;
47
47
  product_note?: string;
48
+ allergy?: string;
48
49
  options?: Array<{
49
50
  name: string;
50
51
  num?: number;
@@ -319,6 +319,7 @@ function buildBaseData(params) {
319
319
  }
320
320
  function buildProducts(order, locale, productMap) {
321
321
  var products = Array.isArray(order.products) ? order.products : [];
322
+ var allergyByProductUid = buildProductAllergyMap(order, locale);
322
323
  return products.map(function (rawProduct) {
323
324
  var _ref, _ref2, _product$product_quan, _ref3, _ref4, _ref5, _product$original_pri, _ref6, _ref7, _product$selling_pric, _product$product_id, _product$metadata, _product$metadata2;
324
325
  var product = restoreReceiptDiscountHierarchy(rawProduct);
@@ -360,10 +361,11 @@ function buildProducts(order, locale, productMap) {
360
361
  originalPrice: originalPrice
361
362
  });
362
363
  var productNote = resolveProductNote(product, locale);
364
+ var allergy = isPresentId(productUid) ? allergyByProductUid.get(String(productUid).trim()) || '' : '';
363
365
  var basePrice = resolveProductBasePrice(product);
364
366
  var resolvedCombinations = Array.isArray(product.combinations) && product.combinations.length ? normalizeExistingCombinations(product.combinations, locale, currencySymbol) : combinations;
365
367
  var shouldIncludeBasePrice = options.length > 0 || resolvedCombinations.length > 0 || hasProductDiscount(product, extensionList);
366
- return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
368
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
367
369
  product_title: productTitle,
368
370
  product_quantity: quantity,
369
371
  selling_price: formatMoney(sellingPrice, currencySymbol),
@@ -385,6 +387,8 @@ function buildProducts(order, locale, productMap) {
385
387
  booking_uid: bookingUid
386
388
  } : {}), productNote ? {
387
389
  product_note: productNote
390
+ } : {}), allergy ? {
391
+ allergy: allergy
388
392
  } : {}), options.length ? {
389
393
  options: options
390
394
  } : {}), resolvedVariant ? {
@@ -810,6 +814,25 @@ function resolveProductNote(product, locale) {
810
814
  if (productNote) return productNote;
811
815
  return getLocalizedValue(product.note, locale).trim();
812
816
  }
817
+ function buildProductAllergyMap(order, locale) {
818
+ var allergyByProductUid = new Map();
819
+ for (var _i = 0, _normalizeArray = normalizeArray(order.notes); _i < _normalizeArray.length; _i++) {
820
+ var _note$content, _relation$target_uuid;
821
+ var note = _normalizeArray[_i];
822
+ if (!note || _typeof(note) !== 'object' || Array.isArray(note) || String(note.note_type || '').trim() !== 'allergy') {
823
+ continue;
824
+ }
825
+ var content = getLocalizedValue((_note$content = note.content) === null || _note$content === void 0 ? void 0 : _note$content.text, locale).trim();
826
+ if (!content) continue;
827
+ var relation = normalizeArray(note.note_relations).find(function (item) {
828
+ return item && _typeof(item) === 'object' && !Array.isArray(item) && item.relation_type === 'about' && item.target_type === 'order_detail' && Number(item.is_primary) === 1;
829
+ });
830
+ var productUid = String((_relation$target_uuid = relation === null || relation === void 0 ? void 0 : relation.target_uuid) !== null && _relation$target_uuid !== void 0 ? _relation$target_uuid : '').trim();
831
+ if (!productUid || allergyByProductUid.has(productUid)) continue;
832
+ allergyByProductUid.set(productUid, content);
833
+ }
834
+ return allergyByProductUid;
835
+ }
813
836
  function resolveBundleProductTitle(params) {
814
837
  var _ref29, _ref30, _bundle$bundle_produc;
815
838
  var bundle = params.bundle,
@@ -1043,9 +1066,9 @@ function buildFees(params) {
1043
1066
  currencySymbol = params.currencySymbol,
1044
1067
  financials = params.financials;
1045
1068
  var fees = [];
1046
- for (var _i = 0, _normalizeArray = normalizeArray(order.surcharges || summary.surcharges); _i < _normalizeArray.length; _i++) {
1069
+ for (var _i2 = 0, _normalizeArray2 = normalizeArray(order.surcharges || summary.surcharges); _i2 < _normalizeArray2.length; _i2++) {
1047
1070
  var _ref48, _surcharge$amount;
1048
- var surcharge = _normalizeArray[_i];
1071
+ var surcharge = _normalizeArray2[_i2];
1049
1072
  var value = (_ref48 = (_surcharge$amount = surcharge.amount) !== null && _surcharge$amount !== void 0 ? _surcharge$amount : surcharge.value) !== null && _ref48 !== void 0 ? _ref48 : surcharge.total_amount;
1050
1073
  if (!isNonZero(value)) continue;
1051
1074
  fees.push({
@@ -1266,8 +1289,8 @@ function firstValidBookingDate() {
1266
1289
  for (var _len2 = arguments.length, values = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1267
1290
  values[_key2] = arguments[_key2];
1268
1291
  }
1269
- for (var _i2 = 0, _values = values; _i2 < _values.length; _i2++) {
1270
- var value = _values[_i2];
1292
+ for (var _i3 = 0, _values = values; _i3 < _values.length; _i3++) {
1293
+ var value = _values[_i3];
1271
1294
  if (!isPresentId(value)) continue;
1272
1295
  var parsed = dayjs(value);
1273
1296
  if (parsed.isValid()) return parsed;
@@ -1324,9 +1347,9 @@ function sortBookings(bookings) {
1324
1347
  var leftStart = bookingStartTimestamp(left.booking);
1325
1348
  var rightStart = bookingStartTimestamp(right.booking);
1326
1349
  if (leftStart !== rightStart) return leftStart < rightStart ? -1 : 1;
1327
- for (var _i3 = 0, _arr = ['booking_id', 'schedule_event_id']; _i3 < _arr.length; _i3++) {
1350
+ for (var _i4 = 0, _arr = ['booking_id', 'schedule_event_id']; _i4 < _arr.length; _i4++) {
1328
1351
  var _left$booking, _right$booking;
1329
- var field = _arr[_i3];
1352
+ var field = _arr[_i4];
1330
1353
  var fieldOrder = compareOptionalValues((_left$booking = left.booking) === null || _left$booking === void 0 ? void 0 : _left$booking[field], (_right$booking = right.booking) === null || _right$booking === void 0 ? void 0 : _right$booking[field]);
1331
1354
  if (fieldOrder !== 0) return fieldOrder;
1332
1355
  }
@@ -1339,8 +1362,8 @@ function sortBookings(bookings) {
1339
1362
  }
1340
1363
  function bookingStartTimestamp(booking) {
1341
1364
  var startValues = [booking === null || booking === void 0 ? void 0 : booking.start_at, booking === null || booking === void 0 ? void 0 : booking.start_datetime, booking === null || booking === void 0 ? void 0 : booking.booking_time, isPresentId(booking === null || booking === void 0 ? void 0 : booking.start_date) ? "".concat(booking.start_date, " ").concat(stringify(booking.start_time)).trim() : undefined];
1342
- for (var _i4 = 0, _startValues = startValues; _i4 < _startValues.length; _i4++) {
1343
- var startValue = _startValues[_i4];
1365
+ for (var _i5 = 0, _startValues = startValues; _i5 < _startValues.length; _i5++) {
1366
+ var startValue = _startValues[_i5];
1344
1367
  if (!isPresentId(startValue)) continue;
1345
1368
  var timestamp = dayjs(startValue).valueOf();
1346
1369
  if (Number.isFinite(timestamp)) return timestamp;
@@ -1466,17 +1489,20 @@ function resolveRefundPayment(refund, payments) {
1466
1489
  return matchedPayment || refund;
1467
1490
  }
1468
1491
  function buildWallets(params) {
1492
+ var virtualCurrencySnapshots = collectVirtualCurrencySnapshots(params.order);
1469
1493
  var displayedWalletPayments = normalizeArray(params.order.payments).filter(function (payment) {
1470
1494
  return isPrintablePayment(payment) && !!getFundRecord(payment);
1471
1495
  });
1472
1496
  var paymentWallets = displayedWalletPayments.map(function (payment) {
1497
+ var virtualCurrencySnapshot = findVirtualCurrencySnapshotForPayment(payment, virtualCurrencySnapshots.byId);
1473
1498
  return buildPaymentItems({
1474
1499
  payment: payment,
1475
1500
  locale: params.locale,
1476
1501
  currencySymbol: params.currencySymbol,
1477
1502
  includeFundRecordBalance: true,
1478
1503
  includeFundRecordUsage: false,
1479
- includePaymentAmount: false
1504
+ includePaymentAmount: false,
1505
+ virtualCurrencyUnit: virtualCurrencySnapshot ? getVirtualCurrencySnapshotUnit(virtualCurrencySnapshot, params.locale) : undefined
1480
1506
  });
1481
1507
  });
1482
1508
  var displayedWalletPassIds = collectDisplayedWalletPassIds(displayedWalletPayments);
@@ -1484,6 +1510,11 @@ function buildWallets(params) {
1484
1510
  order: params.order,
1485
1511
  locale: params.locale,
1486
1512
  displayedWalletPassIds: displayedWalletPassIds
1513
+ })), _toConsumableArray(buildVirtualCurrencySnapshotAssets({
1514
+ snapshots: virtualCurrencySnapshots.items,
1515
+ order: params.order,
1516
+ locale: params.locale,
1517
+ displayedWalletPassIds: displayedWalletPassIds
1487
1518
  })));
1488
1519
  }
1489
1520
  function collectDisplayedWalletPassIds(payments) {
@@ -1531,6 +1562,91 @@ function buildPointCardSnapshotAssets(params) {
1531
1562
  return [rows];
1532
1563
  });
1533
1564
  }
1565
+ function collectVirtualCurrencySnapshots(order) {
1566
+ var _order$order_meta_lis;
1567
+ var items = [];
1568
+ var byId = new Map();
1569
+ var snapshots = (_order$order_meta_lis = order.order_meta_list) === null || _order$order_meta_lis === void 0 ? void 0 : _order$order_meta_lis.virtual_currency_snapshot;
1570
+ if (!Array.isArray(snapshots)) return {
1571
+ items: items,
1572
+ byId: byId
1573
+ };
1574
+ snapshots.forEach(function (snapshot) {
1575
+ if (!snapshot || _typeof(snapshot) !== 'object' || Array.isArray(snapshot)) return;
1576
+ var virtualCurrency = snapshot;
1577
+ if (stringify(virtualCurrency.tag).trim().toLowerCase() !== 'virtual_currency') return;
1578
+ var id = normalizeWalletPassId(virtualCurrency.id);
1579
+ if (!id || byId.has(id)) return;
1580
+ byId.set(id, virtualCurrency);
1581
+ items.push(virtualCurrency);
1582
+ });
1583
+ return {
1584
+ items: items,
1585
+ byId: byId
1586
+ };
1587
+ }
1588
+ function findVirtualCurrencySnapshotForPayment(payment, snapshotsById) {
1589
+ var fundRecord = getFundRecord(payment);
1590
+ for (var _i6 = 0, _arr2 = [fundRecord === null || fundRecord === void 0 ? void 0 : fundRecord.voucher_id, payment.voucher_id]; _i6 < _arr2.length; _i6++) {
1591
+ var value = _arr2[_i6];
1592
+ var id = normalizeWalletPassId(value);
1593
+ if (!id) continue;
1594
+ var snapshot = snapshotsById.get(id);
1595
+ if (snapshot) return snapshot;
1596
+ }
1597
+ return undefined;
1598
+ }
1599
+ function buildVirtualCurrencySnapshotAssets(params) {
1600
+ var snapshotTime = firstPresentValue(params.order.updated_at, params.order.created_at);
1601
+ return params.snapshots.flatMap(function (virtualCurrency) {
1602
+ var id = normalizeWalletPassId(virtualCurrency.id);
1603
+ if (!id || params.displayedWalletPassIds.has(id)) return [];
1604
+ var rows = [{
1605
+ item: stringify(virtualCurrency.product_name).trim(),
1606
+ value: ''
1607
+ }];
1608
+ var balance = getVirtualCurrencySnapshotBalance(virtualCurrency);
1609
+ if (balance) {
1610
+ rows.push({
1611
+ item: label(params.locale, 'balance'),
1612
+ value: formatVirtualCurrencyBalance(balance, getVirtualCurrencySnapshotUnit(virtualCurrency, params.locale))
1613
+ });
1614
+ }
1615
+ if (isPresentId(snapshotTime)) {
1616
+ rows.push({
1617
+ item: formatDateTime(snapshotTime, params.locale),
1618
+ value: ''
1619
+ });
1620
+ }
1621
+ return [rows];
1622
+ });
1623
+ }
1624
+ function getVirtualCurrencySnapshotBalance(snapshot) {
1625
+ if (!isNumericAmount(snapshot.par_value) || !isNumericAmount(snapshot.used_par_value)) {
1626
+ return null;
1627
+ }
1628
+ return Decimal.max(new Decimal(snapshot.par_value).minus(new Decimal(snapshot.used_par_value)), 0);
1629
+ }
1630
+ function getVirtualCurrencySnapshotUnit(snapshot, locale) {
1631
+ return getNonEmptyLocalizedValue(snapshot.name, locale);
1632
+ }
1633
+ function getNonEmptyLocalizedValue(value, locale) {
1634
+ if (value === undefined || value === null) return '';
1635
+ if (_typeof(value) !== 'object' || Array.isArray(value)) return stringify(value).trim();
1636
+ var dashedLocale = locale.replace('_', '-');
1637
+ var underscoredLocale = locale.replace('-', '_');
1638
+ for (var _i7 = 0, _arr3 = [value[locale], value[dashedLocale], value[underscoredLocale], value.original, value.auto, value.default, value.en]; _i7 < _arr3.length; _i7++) {
1639
+ var candidate = _arr3[_i7];
1640
+ var text = stringify(candidate).trim();
1641
+ if (text) return text;
1642
+ }
1643
+ return '';
1644
+ }
1645
+ function formatVirtualCurrencyBalance(value, unit) {
1646
+ var amount = trimDecimal(value);
1647
+ var normalizedUnit = unit.trim();
1648
+ return normalizedUnit ? "".concat(amount, " ").concat(normalizedUnit) : amount;
1649
+ }
1534
1650
  function normalizeWalletPassId(value) {
1535
1651
  if (typeof value === 'number') return Number.isFinite(value) ? String(value) : null;
1536
1652
  if (typeof value !== 'string') return null;
@@ -1583,8 +1699,9 @@ function buildVoucherAssets(params) {
1583
1699
  }].concat(_toConsumableArray(timeRow ? [timeRow] : []))];
1584
1700
  });
1585
1701
  }
1702
+ var TICKET_VOUCHER_TAGS = new Set(['ticket', 'product_package_ticket', 'appointment_ticket', 'session_ticket']);
1586
1703
  function isTicketVoucher(voucher) {
1587
- return stringify(voucher.tag).trim().toLowerCase() === 'ticket';
1704
+ return TICKET_VOUCHER_TAGS.has(stringify(voucher.tag).trim().toLowerCase());
1588
1705
  }
1589
1706
  function getVoucherValidity(voucher, locale) {
1590
1707
  var _voucher$metadata, _voucher$metadata2, _voucher$metadata3, _voucher$metadata4, _voucher$metadata5, _voucher$metadata6, _voucher$metadata7, _voucher$metadata8, _voucher$metadata9, _voucher$metadata10, _voucher$start_time, _voucher$metadata11, _voucher$end_time, _voucher$metadata12;
@@ -1700,7 +1817,8 @@ function buildPaymentItems(params) {
1700
1817
  currencySymbol = params.currencySymbol,
1701
1818
  includeFundRecordBalance = params.includeFundRecordBalance,
1702
1819
  includeFundRecordUsage = params.includeFundRecordUsage,
1703
- includePaymentAmount = params.includePaymentAmount;
1820
+ includePaymentAmount = params.includePaymentAmount,
1821
+ virtualCurrencyUnit = params.virtualCurrencyUnit;
1704
1822
  var serviceFee = getPaymentServiceFee(payment);
1705
1823
  var items = [{
1706
1824
  item: paymentMethodName(payment, locale),
@@ -1725,7 +1843,8 @@ function buildPaymentItems(params) {
1725
1843
  locale: locale,
1726
1844
  currencySymbol: currencySymbol,
1727
1845
  includeBalance: includeFundRecordBalance,
1728
- includeUsage: includeFundRecordUsage
1846
+ includeUsage: includeFundRecordUsage,
1847
+ virtualCurrencyUnit: virtualCurrencyUnit
1729
1848
  })));
1730
1849
  } else {
1731
1850
  var _ref59, _payment$remaining_am, _payment$metadata;
@@ -1790,7 +1909,8 @@ function buildFundRecordPaymentItems(params) {
1790
1909
  locale = params.locale,
1791
1910
  currencySymbol = params.currencySymbol,
1792
1911
  includeBalance = params.includeBalance,
1793
- includeUsage = params.includeUsage;
1912
+ includeUsage = params.includeUsage,
1913
+ virtualCurrencyUnit = params.virtualCurrencyUnit;
1794
1914
  var items = [];
1795
1915
  var usingBeforeValue = fundRecord.using_before_value;
1796
1916
  var usingAfterValue = fundRecord.using_after_value;
@@ -1811,6 +1931,14 @@ function buildFundRecordPaymentItems(params) {
1811
1931
  return items;
1812
1932
  }
1813
1933
  if (includeBalance && usingAfterValue !== undefined && usingAfterValue !== null) {
1934
+ if (virtualCurrencyUnit !== undefined) {
1935
+ if (!isNumericAmount(usingAfterValue)) return items;
1936
+ items.push({
1937
+ item: label(locale, 'balance'),
1938
+ value: formatVirtualCurrencyBalance(new Decimal(usingAfterValue), virtualCurrencyUnit)
1939
+ });
1940
+ return items;
1941
+ }
1814
1942
  items.push({
1815
1943
  item: label(locale, 'balance'),
1816
1944
  value: formatMoney(usingAfterValue, currencySymbol)
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
3
  import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
4
4
  import { OrderModule } from '../../modules/Order';
5
- import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions } from '../../modules/Order/types';
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';
7
7
  import type { Discount, VirtualCurrencyAsset } from '../../modules/Discount/types';
8
8
  import { RequestPlugin, WindowPlugin } from '../../plugins';
@@ -232,6 +232,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
232
232
  getOrderSyncState(): import("../../modules/Order/types").OrderSyncState;
233
233
  getOrderAmountSnapshot(): import("../../modules/Order/types").OrderAmountSnapshot | null;
234
234
  getTempOrderNote(): string;
235
+ getSalesNotes(): SalesNote[];
236
+ createSalesNotesMutationSnapshot(): SalesNotesMutationSnapshot;
237
+ restoreSalesNotesMutationSnapshot(snapshot: SalesNotesMutationSnapshot): void;
238
+ setSalesNote(input: SetSalesNoteInput): Promise<SalesNote>;
239
+ removeSalesNote(uuid: string): Promise<void>;
240
+ clearSalesNotes(): Promise<void>;
235
241
  updateTempOrderNote(note: string): string;
236
242
  updateTempOrderNote(note: string, sync: true): Promise<string>;
237
243
  updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
@@ -240,6 +246,8 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
240
246
  setPickupRef(buzzer: string): string;
241
247
  updateTempOrderShopDiscount(amount: string | number): string;
242
248
  updateTempOrderDepositAmount(amount: string | number): OrderSummary;
249
+ setPickupReferenceMode(mode: PickupReferenceMode): ShopServiceData;
250
+ setServiceType(serviceType: ShopServiceType): ShopServiceData;
243
251
  updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
244
252
  /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
245
253
  setEnableTempOrderPersist(enabled: boolean): void;
@@ -263,6 +271,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
263
271
  private mergeHistoricalDiscountList;
264
272
  private shouldSkipAutoApplyFetchedDiscountsInEditMode;
265
273
  private mergeCurrentDiscountSelectionState;
274
+ private resolveDiscountConfigCustomerId;
275
+ /**
276
+ * Stable across notifyTempOrderChanged's immutable object replacement, while
277
+ * still distinguishing two local orders for the same customer.
278
+ */
279
+ private getDiscountConfigOrderIdentityKey;
266
280
  loadDiscountConfig(params?: {
267
281
  customerId?: number;
268
282
  action?: 'create' | 'edit';