@pisell/pisellos 2.2.301 → 2.2.303

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 (152) hide show
  1. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  2. package/dist/model/strategy/adapter/dataVariant/evaluator.js +287 -101
  3. package/dist/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  4. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  5. package/dist/model/strategy/adapter/itemRule/adapter.js +135 -35
  6. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  7. package/dist/model/strategy/adapter/itemRule/evaluator.js +25 -1
  8. package/dist/model/strategy/adapter/itemRule/type.d.ts +44 -0
  9. package/dist/model/strategy/adapter/itemRule/type.js +19 -1
  10. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +10 -7
  11. package/dist/modules/Discount/index.d.ts +2 -0
  12. package/dist/modules/Discount/index.js +41 -5
  13. package/dist/modules/Discount/types.d.ts +21 -0
  14. package/dist/modules/OpenData/index.d.ts +15 -2
  15. package/dist/modules/OpenData/index.js +307 -19
  16. package/dist/modules/OpenData/types.d.ts +55 -0
  17. package/dist/modules/OpenData/types.js +7 -1
  18. package/dist/modules/OpenData/utils.d.ts +21 -1
  19. package/dist/modules/OpenData/utils.js +138 -0
  20. package/dist/modules/Order/index.d.ts +50 -7
  21. package/dist/modules/Order/index.js +1690 -815
  22. package/dist/modules/Order/salesNotes.d.ts +31 -0
  23. package/dist/modules/Order/salesNotes.js +492 -0
  24. package/dist/modules/Order/types.d.ts +117 -10
  25. package/dist/modules/Order/types.js +6 -1
  26. package/dist/modules/Order/utils/virtualSettlement.d.ts +63 -0
  27. package/dist/modules/Order/utils/virtualSettlement.js +284 -0
  28. package/dist/modules/Order/utils.d.ts +5 -1
  29. package/dist/modules/Order/utils.js +138 -33
  30. package/dist/modules/Payment/walletpass.js +20 -21
  31. package/dist/modules/Product/types.d.ts +23 -0
  32. package/dist/modules/ProductList/index.d.ts +2 -1
  33. package/dist/modules/ProductList/index.js +100 -20
  34. package/dist/modules/ProductList/types.d.ts +10 -0
  35. package/dist/modules/Rules/index.d.ts +5 -0
  36. package/dist/modules/Rules/index.js +30 -14
  37. package/dist/modules/SalesSummary/index.d.ts +1 -0
  38. package/dist/modules/SalesSummary/index.js +4 -3
  39. package/dist/modules/SalesSummary/types.d.ts +1 -0
  40. package/dist/modules/SalesSummary/utils.d.ts +1 -0
  41. package/dist/modules/SalesSummary/utils.js +21 -1
  42. package/dist/plugins/request.d.ts +2 -1
  43. package/dist/plugins/request.js +4 -2
  44. package/dist/server/index.d.ts +21 -0
  45. package/dist/server/index.js +1774 -1285
  46. package/dist/server/modules/order/types.d.ts +50 -0
  47. package/dist/server/modules/order/types.js +2 -0
  48. package/dist/server/utils/small-ticket.d.ts +4 -1
  49. package/dist/server/utils/small-ticket.js +461 -96
  50. package/dist/solution/BaseSales/index.d.ts +26 -3
  51. package/dist/solution/BaseSales/index.js +1492 -873
  52. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  53. package/dist/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  54. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  55. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +72 -9
  56. package/dist/solution/BookingByStep/index.d.ts +1 -1
  57. package/dist/solution/BookingTicket/index.d.ts +8 -3
  58. package/dist/solution/BookingTicket/index.js +558 -443
  59. package/dist/solution/BookingTicket/utils/addProductDecision.js +2 -1
  60. package/dist/solution/BookingTicket/utils/orderCustomer.js +3 -2
  61. package/dist/solution/RegisterAndLogin/config.d.ts +9 -3
  62. package/dist/solution/RegisterAndLogin/config.js +95 -40
  63. package/dist/solution/RegisterAndLogin/index.js +4 -1
  64. package/dist/solution/Sales/index.d.ts +16 -1
  65. package/dist/solution/Sales/index.js +338 -63
  66. package/dist/solution/Sales/types.d.ts +10 -0
  67. package/dist/solution/ScanOrder/index.d.ts +1 -0
  68. package/dist/solution/ScanOrder/index.js +31 -27
  69. package/dist/solution/ScanOrder/utils.d.ts +1 -0
  70. package/dist/solution/ScanOrder/utils.js +2 -0
  71. package/dist/solution/UnifiedBookingSales/index.d.ts +20 -6
  72. package/dist/solution/UnifiedBookingSales/index.js +874 -527
  73. package/dist/solution/UnifiedBookingSales/types.d.ts +21 -2
  74. package/dist/solution/VenueBooking/index.d.ts +1 -0
  75. package/dist/solution/VenueBooking/index.js +8 -4
  76. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  77. package/lib/model/strategy/adapter/dataVariant/evaluator.js +137 -6
  78. package/lib/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  79. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +4 -1
  80. package/lib/model/strategy/adapter/itemRule/adapter.js +73 -4
  81. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +8 -1
  82. package/lib/model/strategy/adapter/itemRule/evaluator.js +23 -1
  83. package/lib/model/strategy/adapter/itemRule/type.d.ts +44 -0
  84. package/lib/model/strategy/adapter/itemRule/type.js +19 -1
  85. package/lib/model/strategy/adapter/promotion/index.js +1 -46
  86. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +4 -0
  87. package/lib/modules/Discount/index.d.ts +2 -0
  88. package/lib/modules/Discount/index.js +34 -2
  89. package/lib/modules/Discount/types.d.ts +21 -0
  90. package/lib/modules/OpenData/index.d.ts +15 -2
  91. package/lib/modules/OpenData/index.js +230 -3
  92. package/lib/modules/OpenData/types.d.ts +55 -0
  93. package/lib/modules/OpenData/types.js +9 -1
  94. package/lib/modules/OpenData/utils.d.ts +21 -1
  95. package/lib/modules/OpenData/utils.js +126 -0
  96. package/lib/modules/Order/index.d.ts +50 -7
  97. package/lib/modules/Order/index.js +704 -64
  98. package/lib/modules/Order/salesNotes.d.ts +31 -0
  99. package/lib/modules/Order/salesNotes.js +382 -0
  100. package/lib/modules/Order/types.d.ts +117 -10
  101. package/lib/modules/Order/types.js +5 -1
  102. package/lib/modules/Order/utils/virtualSettlement.d.ts +63 -0
  103. package/lib/modules/Order/utils/virtualSettlement.js +262 -0
  104. package/lib/modules/Order/utils.d.ts +5 -1
  105. package/lib/modules/Order/utils.js +127 -21
  106. package/lib/modules/Payment/walletpass.js +14 -11
  107. package/lib/modules/Product/types.d.ts +23 -0
  108. package/lib/modules/ProductList/index.d.ts +2 -1
  109. package/lib/modules/ProductList/index.js +47 -2
  110. package/lib/modules/ProductList/types.d.ts +10 -0
  111. package/lib/modules/Rules/index.d.ts +5 -0
  112. package/lib/modules/Rules/index.js +22 -12
  113. package/lib/modules/SalesSummary/index.d.ts +1 -0
  114. package/lib/modules/SalesSummary/index.js +4 -2
  115. package/lib/modules/SalesSummary/types.d.ts +1 -0
  116. package/lib/modules/SalesSummary/utils.d.ts +1 -0
  117. package/lib/modules/SalesSummary/utils.js +17 -1
  118. package/lib/plugins/request.d.ts +2 -1
  119. package/lib/plugins/request.js +3 -2
  120. package/lib/server/index.d.ts +21 -0
  121. package/lib/server/index.js +492 -108
  122. package/lib/server/modules/order/types.d.ts +50 -0
  123. package/lib/server/modules/order/types.js +1 -0
  124. package/lib/server/utils/small-ticket.d.ts +4 -1
  125. package/lib/server/utils/small-ticket.js +427 -72
  126. package/lib/solution/BaseSales/index.d.ts +26 -3
  127. package/lib/solution/BaseSales/index.js +439 -30
  128. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  129. package/lib/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  130. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  131. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +38 -0
  132. package/lib/solution/BookingByStep/index.d.ts +1 -1
  133. package/lib/solution/BookingTicket/index.d.ts +8 -3
  134. package/lib/solution/BookingTicket/index.js +60 -15
  135. package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -0
  136. package/lib/solution/BookingTicket/utils/orderCustomer.js +2 -1
  137. package/lib/solution/RegisterAndLogin/config.d.ts +9 -3
  138. package/lib/solution/RegisterAndLogin/config.js +49 -8
  139. package/lib/solution/RegisterAndLogin/index.js +4 -1
  140. package/lib/solution/Sales/index.d.ts +16 -1
  141. package/lib/solution/Sales/index.js +168 -1
  142. package/lib/solution/Sales/types.d.ts +10 -0
  143. package/lib/solution/ScanOrder/index.d.ts +1 -0
  144. package/lib/solution/ScanOrder/index.js +5 -1
  145. package/lib/solution/ScanOrder/utils.d.ts +1 -0
  146. package/lib/solution/ScanOrder/utils.js +1 -0
  147. package/lib/solution/UnifiedBookingSales/index.d.ts +20 -6
  148. package/lib/solution/UnifiedBookingSales/index.js +169 -16
  149. package/lib/solution/UnifiedBookingSales/types.d.ts +21 -2
  150. package/lib/solution/VenueBooking/index.d.ts +1 -0
  151. package/lib/solution/VenueBooking/index.js +5 -1
  152. package/package.json +1 -1
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "buildManualProductDiscountItem", {
9
9
  return _manualProductDiscount.buildManualProductDiscountItem;
10
10
  }
11
11
  });
12
+ exports.buildPointCardSnapshotFromWalletPassList = buildPointCardSnapshotFromWalletPassList;
12
13
  exports.buildSubmitPayload = buildSubmitPayload;
13
14
  exports.calculateOrderProductsDeposit = calculateOrderProductsDeposit;
14
15
  exports.clearTempOrderHolderAssignments = clearTempOrderHolderAssignments;
@@ -67,7 +68,9 @@ exports.mergeOrderProductDisplayFields = mergeOrderProductDisplayFields;
67
68
  exports.mergeRelationForms = void 0;
68
69
  exports.normalizeBookingIsAll = normalizeBookingIsAll;
69
70
  exports.normalizeBookingSubType = normalizeBookingSubType;
71
+ exports.normalizeOrderMetaList = normalizeOrderMetaList;
70
72
  exports.normalizeOrderProductDiscountList = normalizeOrderProductDiscountList;
73
+ exports.normalizePointCardSnapshotItem = normalizePointCardSnapshotItem;
71
74
  exports.normalizeProductSkuOptions = normalizeProductSkuOptions;
72
75
  exports.normalizeSubmitBooking = normalizeSubmitBooking;
73
76
  exports.normalizeSubmitCollectPaxValue = normalizeSubmitCollectPaxValue;
@@ -126,8 +129,58 @@ var _decimal = _interopRequireDefault(require("decimal.js"));
126
129
  var _utils = require("../Holder/utils");
127
130
  var _utils2 = require("../../solution/ScanOrder/utils");
128
131
  var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
132
+ var _salesNotes = require("./salesNotes");
129
133
  var _manualProductDiscount = require("./utils/manualProductDiscount");
130
134
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
135
+ const POINT_CARD_SNAPSHOT_TAG = 'point_card';
136
+ function isPlainObject(value) {
137
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
138
+ }
139
+ function normalizeSnapshotScalar(value) {
140
+ if (value === undefined || value === null) return undefined;
141
+ if (typeof value === 'string') return value.trim() ? value : undefined;
142
+ if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;
143
+ return undefined;
144
+ }
145
+ function normalizePointCardSnapshotItem(value) {
146
+ if (!isPlainObject(value)) return null;
147
+ const id = normalizeSnapshotScalar(value.id);
148
+ if (id === undefined) return null;
149
+ if (String(value.tag || '').trim().toLowerCase() !== POINT_CARD_SNAPSHOT_TAG) {
150
+ return null;
151
+ }
152
+ const snapshot = {
153
+ id,
154
+ tag: 'point_card',
155
+ product_name: String(value.product_name ?? ''),
156
+ par_value: String(value.par_value ?? ''),
157
+ used_par_value: String(value.used_par_value ?? '')
158
+ };
159
+ const productId = normalizeSnapshotScalar(value.product_id);
160
+ if (productId !== undefined) {
161
+ snapshot.product_id = productId;
162
+ }
163
+ return snapshot;
164
+ }
165
+ function buildPointCardSnapshotFromWalletPassList(value) {
166
+ if (!Array.isArray(value)) return [];
167
+ return value.reduce((result, item) => {
168
+ const normalized = normalizePointCardSnapshotItem(item);
169
+ if (normalized) result.push(normalized);
170
+ return result;
171
+ }, []);
172
+ }
173
+ function normalizeOrderMetaList(value) {
174
+ if (value === undefined) return undefined;
175
+ if (!isPlainObject(value)) return undefined;
176
+ const normalized = {};
177
+ if (Object.prototype.hasOwnProperty.call(value, 'point_cards_snapshot')) {
178
+ normalized.point_cards_snapshot = buildPointCardSnapshotFromWalletPassList(value.point_cards_snapshot);
179
+ }
180
+ if (Object.keys(normalized).length > 0) return normalized;
181
+ return {};
182
+ }
183
+
131
184
  /**
132
185
  * 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
133
186
  *
@@ -863,7 +916,7 @@ function normalizeSubmitProductionCode(value) {
863
916
  }
864
917
 
865
918
  // 后端 checkout 协议字段 option_group_item_id;tempOrder 内部也保持同一字段名。
866
- function formatSubmitOptionItems(options) {
919
+ function formatSubmitOptionItems(options, formatOptions = {}) {
867
920
  if (!Array.isArray(options)) return [];
868
921
  return options.map(d => {
869
922
  const option = {
@@ -876,7 +929,11 @@ function formatSubmitOptionItems(options) {
876
929
  delete option.production_code;
877
930
  if (productionCode !== undefined) option.production_code = productionCode;
878
931
  const addPrice = d?.add_price ?? d?.price;
879
- if (addPrice !== undefined) option.add_price = String(addPrice);
932
+ if (formatOptions.virtualSettlementMode) {
933
+ option.add_price = 0;
934
+ } else if (addPrice !== undefined) {
935
+ option.add_price = String(addPrice);
936
+ }
880
937
  delete option.price;
881
938
  return option;
882
939
  });
@@ -893,7 +950,7 @@ function toMoneyString(value) {
893
950
  }
894
951
 
895
952
  // 出站补齐:只输出后端 checkout 协议字段,运行时/详情展示字段不进入 bundle payload。
896
- function formatSubmitBundleItems(bundle) {
953
+ function formatSubmitBundleItems(bundle, formatOptions = {}) {
897
954
  if (!Array.isArray(bundle)) return [];
898
955
  return bundle.map(b => {
899
956
  const rawBundle = b && typeof b === 'object' ? b : {};
@@ -905,10 +962,10 @@ function formatSubmitBundleItems(bundle) {
905
962
 
906
963
  // bundle_selling_price 出站存「正净额」:markdown 为 |price| − Σoptions(如 3.70),
907
964
  // markup/原价维持原值;与后端口径一致(price 仍为毛价)。
908
- const sellingPrice = getBundleSellingMagnitude(rawBundle).toFixed(2);
965
+ const sellingPrice = formatOptions.virtualSettlementMode ? '0.00' : getBundleSellingMagnitude(rawBundle).toFixed(2);
909
966
  // payment 价由整单折扣均摊层产出;缺省(无折扣)时与 selling 净额同义。
910
- const paymentPrice = rawBundle.bundle_payment_price !== undefined && rawBundle.bundle_payment_price !== null && rawBundle.bundle_payment_price !== '' ? toMoneyString(rawBundle.bundle_payment_price) : sellingPrice;
911
- const priceValue = rawBundle.price ?? rawBundle.custom_price ?? rawBundle.bundle_selling_price;
967
+ const paymentPrice = formatOptions.virtualSettlementMode ? '0.00' : rawBundle.bundle_payment_price !== undefined && rawBundle.bundle_payment_price !== null && rawBundle.bundle_payment_price !== '' ? toMoneyString(rawBundle.bundle_payment_price) : sellingPrice;
968
+ const priceValue = formatOptions.virtualSettlementMode ? 0 : rawBundle.price ?? rawBundle.custom_price ?? rawBundle.bundle_selling_price;
912
969
  const relationSurchargeIds = Array.isArray(rawBundle.relation_surcharge_ids) ? rawBundle.relation_surcharge_ids : Array.isArray(existedMetadata.relation_surcharge_ids) ? existedMetadata.relation_surcharge_ids : [];
913
970
  const surchargeFee = toMoneyString(rawBundle.surcharge_fee ?? existedMetadata.surcharge_fee);
914
971
  const productDiscountDifference = toBundleNumber(existedMetadata.product_discount_difference, 0);
@@ -917,7 +974,7 @@ function formatSubmitBundleItems(bundle) {
917
974
  const hasSubmitBundleDiscounts = Array.isArray(rawBundle.discount_list) && rawBundle.discount_list.length > 0;
918
975
  const productionCode = normalizeSubmitProductionCode(rawBundle.production_code);
919
976
  return {
920
- is_charge_tax: rawBundle.is_charge_tax ?? 0,
977
+ is_charge_tax: formatOptions.virtualSettlementMode ? 0 : rawBundle.is_charge_tax ?? 0,
921
978
  bundle_variant_id: rawBundle.bundle_variant_id ?? 0,
922
979
  ...(productionCode !== undefined ? {
923
980
  production_code: productionCode
@@ -931,7 +988,7 @@ function formatSubmitBundleItems(bundle) {
931
988
  price_type_ext: rawBundle.price_type_ext ?? rawBundle.custom_price_type_ext ?? '',
932
989
  bundle_selling_price: sellingPrice,
933
990
  bundle_payment_price: paymentPrice,
934
- option: formatSubmitOptionItems(rawBundle.option),
991
+ option: formatSubmitOptionItems(rawBundle.option, formatOptions),
935
992
  bundle_group_id: rawBundle?.bundle_group_id ?? rawBundle?.group_id,
936
993
  bundle_id: rawBundle?.bundle_id ?? rawBundle?.id,
937
994
  bundle_product_id: rawBundle?.bundle_product_id ?? rawBundle?._bundle_product_id,
@@ -941,9 +998,9 @@ function formatSubmitBundleItems(bundle) {
941
998
  ...(hasSubmitBundleDiscounts && bundleMapId !== undefined ? {
942
999
  custom_product_bundle_map_id: bundleMapId
943
1000
  } : {}),
944
- surcharge_fee: surchargeFee,
945
- relation_surcharge_ids: relationSurchargeIds,
946
- product_discount_difference: productDiscountDifference
1001
+ surcharge_fee: formatOptions.virtualSettlementMode ? '0.00' : surchargeFee,
1002
+ relation_surcharge_ids: formatOptions.virtualSettlementMode ? [] : relationSurchargeIds,
1003
+ product_discount_difference: formatOptions.virtualSettlementMode ? '' : productDiscountDifference
947
1004
  }
948
1005
  };
949
1006
  });
@@ -963,9 +1020,9 @@ function formatSubmitBundleItems(bundle) {
963
1020
  * - `metadata.main_product_selling_price`:含 option、含主商品折扣。
964
1021
  * - `metadata.price_schema_version`:schema 版本号(当前 = 2),用于跨端协商价格口径。
965
1022
  *
966
- * 本函数不再改造价格字段形状,仅做字段/metadata 裁剪。
1023
+ * 法币仅做字段/metadata 裁剪;虚拟币在出站前再次执行零加价与固定单价断言。
967
1024
  */
968
- function normalizeSubmitProduct(product) {
1025
+ function normalizeSubmitProduct(product, formatOptions = {}) {
969
1026
  const {
970
1027
  unique_identification_number: _runtimeUid,
971
1028
  ...submitProduct
@@ -993,7 +1050,7 @@ function normalizeSubmitProduct(product) {
993
1050
  if (rawMetadata.unique_identification_number) {
994
1051
  cleanMetadata.unique_identification_number = rawMetadata.unique_identification_number;
995
1052
  }
996
- const priceMetaKeys = ['main_product_original_price', 'main_product_selling_price', 'main_product_attached_bundle_selling_price', 'main_product_attached_bundle_payment_price', 'average_discount_amount_rate', 'source_product_price', 'main_product_attached_bundle_surcharge_fee', 'main_product_attached_bundle_tax_fee', 'surcharge_rounding_remainder', 'tax_fee_rounding_remainder', 'relation_surcharge_ids', 'discountable_flag', 'parent_unique_identification_number', 'product_add_schedule_time'];
1053
+ const priceMetaKeys = ['main_product_original_price', 'main_product_selling_price', 'main_product_attached_bundle_selling_price', 'main_product_attached_bundle_payment_price', 'average_discount_amount_rate', 'source_product_price', 'main_product_attached_bundle_surcharge_fee', 'main_product_attached_bundle_tax_fee', 'surcharge_rounding_remainder', 'tax_fee_rounding_remainder', 'relation_surcharge_ids', 'discountable_flag', 'price_schema_version', 'parent_unique_identification_number', 'product_add_schedule_time', 'data_variant_ids'];
997
1054
  for (const key of priceMetaKeys) {
998
1055
  if (rawMetadata[key] !== undefined) {
999
1056
  cleanMetadata[key] = rawMetadata[key];
@@ -1009,12 +1066,36 @@ function normalizeSubmitProduct(product) {
1009
1066
  if (rawMetadata.holder_config !== undefined) {
1010
1067
  cleanMetadata.holder_config = rawMetadata.holder_config;
1011
1068
  }
1069
+ const virtualPrice = toMoneyString(rawMetadata.selected_settlement_snapshot?.price ?? submitProduct.selling_price);
1070
+ if (formatOptions.virtualSettlementMode) {
1071
+ Object.assign(cleanMetadata, {
1072
+ source_product_price: virtualPrice,
1073
+ main_product_original_price: virtualPrice,
1074
+ main_product_selling_price: virtualPrice,
1075
+ main_product_attached_bundle_selling_price: virtualPrice,
1076
+ main_product_attached_bundle_payment_price: virtualPrice,
1077
+ main_product_attached_bundle_surcharge_fee: '0.00',
1078
+ main_product_attached_bundle_tax_fee: '0.00',
1079
+ surcharge_rounding_remainder: '0.00',
1080
+ tax_fee_rounding_remainder: '0.00',
1081
+ relation_surcharge_ids: [],
1082
+ average_discount_amount_rate: '1',
1083
+ product_discount_difference: '',
1084
+ discountable_flag: 0,
1085
+ price_schema_version: 2
1086
+ });
1087
+ }
1012
1088
  const productSku = {
1013
1089
  ...(submitProduct.product_sku && typeof submitProduct.product_sku === 'object' ? submitProduct.product_sku : {}),
1014
- option: formatSubmitOptionItems(submitProduct.product_sku?.option)
1090
+ option: formatSubmitOptionItems(submitProduct.product_sku?.option, formatOptions)
1015
1091
  };
1016
1092
  return {
1017
1093
  ...productRest,
1094
+ ...(formatOptions.virtualSettlementMode ? {
1095
+ selling_price: virtualPrice,
1096
+ original_price: virtualPrice,
1097
+ is_charge_tax: 0
1098
+ } : {}),
1018
1099
  ...(productionCode !== undefined ? {
1019
1100
  production_code: productionCode
1020
1101
  } : {}),
@@ -1026,12 +1107,12 @@ function normalizeSubmitProduct(product) {
1026
1107
  } : {}),
1027
1108
  product_quantity: toBundleNumber(num ?? submitProduct.product_quantity, 1),
1028
1109
  product_sku: productSku,
1029
- discount_list: collectSubmitProductDiscountList(submitProduct),
1030
- product_bundle: formatSubmitBundleItems(submitProduct.product_bundle),
1110
+ discount_list: formatOptions.virtualSettlementMode ? [] : collectSubmitProductDiscountList(submitProduct),
1111
+ product_bundle: formatSubmitBundleItems(submitProduct.product_bundle, formatOptions),
1031
1112
  metadata: cleanMetadata,
1032
1113
  // 出站兼容:后端消费 payment_price 字段(行 composite 已减整单折扣均摊)。
1033
1114
  // 由整单折扣均摊层产出;缺省(无折扣)时与 selling_price 同义。
1034
- payment_price: submitProduct.payment_price ?? submitProduct.selling_price
1115
+ payment_price: formatOptions.virtualSettlementMode ? virtualPrice : submitProduct.payment_price ?? submitProduct.selling_price
1035
1116
  };
1036
1117
  }
1037
1118
  const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder'];
@@ -1128,6 +1209,7 @@ function createDefaultTempOrder(params) {
1128
1209
  request_unique_idempotency_token: '',
1129
1210
  vouchers: [],
1130
1211
  products: [],
1212
+ notes: [],
1131
1213
  bookings: [],
1132
1214
  payments: [],
1133
1215
  surcharges: [],
@@ -1137,7 +1219,11 @@ function createDefaultTempOrder(params) {
1137
1219
  holder: null,
1138
1220
  metadata: {},
1139
1221
  _extend: {
1140
- productsByUid: {}
1222
+ productsByUid: {},
1223
+ salesNotesState: {
1224
+ loaded: true,
1225
+ dirty: false
1226
+ }
1141
1227
  }
1142
1228
  };
1143
1229
  }
@@ -1199,6 +1285,7 @@ function buildSubmitPayload(params) {
1199
1285
  } = params;
1200
1286
  const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
1201
1287
  const bookingUuid = (0, _orderCollectionIdentity.createUuidV4)();
1288
+ const virtualSettlementMode = tempOrder.metadata?.currency_settlement_config?.settlement_type === 'virtual_currency';
1202
1289
  const {
1203
1290
  _extend: _extend,
1204
1291
  relation_id: _relationId,
@@ -1213,14 +1300,18 @@ function buildSubmitPayload(params) {
1213
1300
  start_time: _startTime,
1214
1301
  customer: _customer,
1215
1302
  discount_list: _discountList,
1303
+ order_meta_list: _orderMetaList,
1216
1304
  tax_fee: _rootTaxFee,
1217
1305
  total_amount: _totalAmount,
1218
1306
  total_refund_amount: _totalRefundAmount,
1219
1307
  create_date: _createDate,
1220
1308
  holder_id: _holderId,
1309
+ payment_status: _paymentStatus,
1310
+ notes: _notes,
1221
1311
  ...tempOrderRest
1222
1312
  } = tempOrder;
1223
1313
  const resolvedBusinessCode = businessCode ?? tempOrder.business_code;
1314
+ const normalizedOrderMetaList = normalizeOrderMetaList(tempOrder.order_meta_list);
1224
1315
  const submitType = resolveSubmitOrderType({
1225
1316
  requestedType: type,
1226
1317
  tempOrderType: tempOrder.type,
@@ -1246,7 +1337,9 @@ function buildSubmitPayload(params) {
1246
1337
  sales_channel: tempOrder.sales_channel || 'my_pisel',
1247
1338
  order_sales_channel: channel ?? tempOrder.order_sales_channel ?? 'online_store',
1248
1339
  status: tempOrder.status || 'normal',
1249
- payment_status: tempOrder.payment_status || 'payment_processing',
1340
+ ...(params.includePaymentStatus !== false ? {
1341
+ payment_status: tempOrder.payment_status || 'payment_processing'
1342
+ } : {}),
1250
1343
  // shipping_status: tempOrder.shipping_status || 'unfulfilled',
1251
1344
  is_price_include_tax: tempOrder.is_price_include_tax ?? 1,
1252
1345
  currency_format: tempOrder.currency_format || 'symbol_first',
@@ -1269,13 +1362,26 @@ function buildSubmitPayload(params) {
1269
1362
  const {
1270
1363
  collect_pax: _collectPax,
1271
1364
  table_occupancy_duration: _tableOccupancyDuration,
1365
+ cart_settlement_key: _cartSettlementKey,
1366
+ cart_settlement_snapshot: _cartSettlementSnapshot,
1367
+ legal_currency_snapshot: _legalCurrencySnapshot,
1272
1368
  ...rest
1273
1369
  } = tempOrder.metadata || {};
1274
1370
  return {
1275
1371
  ...rest
1276
1372
  };
1277
1373
  })(),
1278
- products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product))
1374
+ ...(tempOrder._extend?.salesNotesState?.dirty ? {
1375
+ notes: (0, _salesNotes.encodeSalesNotes)(tempOrder.notes || [], {
1376
+ allowUnresolvedOrderTarget: true
1377
+ })
1378
+ } : {}),
1379
+ products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product, {
1380
+ virtualSettlementMode
1381
+ })),
1382
+ ...(normalizedOrderMetaList !== undefined ? {
1383
+ order_meta_list: normalizedOrderMetaList
1384
+ } : {})
1279
1385
  };
1280
1386
  if (!enhance) return payload;
1281
1387
  const enhancedPayload = enhance(payload, {
@@ -650,17 +650,20 @@ class WalletPassPaymentImpl {
650
650
  this.paymentModule.logInfo('[WalletPass] 商品列表为空,跳过获取用户识别码列表');
651
651
  return [];
652
652
  }
653
- const platform = this.paymentModule.getPlatform();
654
- if (platform === 'pc' || platform === 'h5') {
655
- this.userIdentificationCodes = [];
656
- this.emitEvent(_types.WalletPassHooks.OnUserIdentificationCodesUpdated, {
657
- userIdentificationCodes: []
658
- });
659
- this.paymentModule.logInfo('[WalletPass] 用户端平台跳过获取用户识别码列表', {
660
- platform
661
- });
662
- return [];
663
- }
653
+
654
+ // const platform = this.paymentModule.getPlatform();
655
+ // if (platform === 'pc' || platform === 'h5') {
656
+ // this.userIdentificationCodes = [];
657
+ // this.emitEvent(WalletPassHooks.OnUserIdentificationCodesUpdated, {
658
+ // userIdentificationCodes: [],
659
+ // } as OnUserIdentificationCodesUpdatedEventData);
660
+ // this.paymentModule.logInfo(
661
+ // '[WalletPass] 用户端平台跳过获取用户识别码列表',
662
+ // { platform },
663
+ // );
664
+ // return [];
665
+ // }
666
+
664
667
  if (typeof newParams.payment_order_id === 'string' && newParams.payment_order_id.startsWith('LOCAL_')) {
665
668
  newParams.payment_order_id = undefined;
666
669
  }
@@ -23,12 +23,25 @@ export interface ProductDataVariant {
23
23
  module_data_id: number;
24
24
  /** 关联 data_variant_rule.id */
25
25
  data_variant_rule_id: number;
26
+ /** 多货币结算等业务类型 */
27
+ business_type?: 'multi_currency_settlement' | string;
28
+ /** 数据状态;多货币结算仅处理 enable 记录 */
29
+ status?: 'enable' | 'disable' | string;
26
30
  /** 命中策略后覆盖到商品上的字段 */
27
31
  data: Record<string, any>;
28
32
  created_at: string | null;
29
33
  updated_at: string | null;
30
34
  deleted_at: string | null;
31
35
  }
36
+ export interface ProductSettlementOption extends Record<string, any> {
37
+ settlement_type: 'legal_currency' | 'virtual_currency' | string;
38
+ currency_product_id?: number;
39
+ price: string;
40
+ data_variant_id?: number;
41
+ data_variant_rule_id: number | string;
42
+ available: boolean;
43
+ disabled_reason?: string;
44
+ }
32
45
  /**
33
46
  * 商品基本信息接口
34
47
  */
@@ -61,6 +74,8 @@ export interface ProductData {
61
74
  sum_stock: number;
62
75
  /** 商品价格 */
63
76
  price: string;
77
+ /** 当前上下文解析出的可选结算货币 */
78
+ available_settlement_options?: ProductSettlementOption[];
64
79
  /** 商品原价 */
65
80
  original_price: string;
66
81
  /** 商品成本价 */
@@ -239,6 +254,14 @@ export interface ProductData {
239
254
  option_group_count: number;
240
255
  /** 智能定价变体列表,/product/query with dataVariants 返回 */
241
256
  data_variants?: ProductDataVariant[];
257
+ /**
258
+ * 商品接口规则计算结果;data_variant_ids 按优先级从高到低排列。
259
+ * 空数组表示规则已经计算完成但没有命中 Data Variant。
260
+ */
261
+ metadata?: {
262
+ data_variant_ids?: Array<number | string>;
263
+ [key: string]: any;
264
+ };
242
265
  /** 服务时长 */
243
266
  service_times?: any;
244
267
  }
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { ProductListLoadProductsParams } from './types';
3
+ import { ProductListLoadProductsParams, ProductListStoreQueryParams } from './types';
4
4
  import { ProductData } from '../Product/types';
5
5
  export * from './types';
6
6
  export declare class ProductList extends BaseModule implements Module {
@@ -52,6 +52,7 @@ export declare class ProductList extends BaseModule implements Module {
52
52
  getRawProductPriceSources(ids: number[]): Map<number, ProductData>;
53
53
  getProducts(): Promise<ProductData[]>;
54
54
  getProduct(id: number): Promise<ProductData | undefined>;
55
+ queryProducts(params?: ProductListStoreQueryParams): Promise<ProductData[]>;
55
56
  getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
56
57
  addProduct(products: ProductData[]): Promise<void>;
57
58
  selectProducts(products: ProductData[]): Promise<void>;
@@ -25,6 +25,15 @@ Object.keys(_types).forEach(function (key) {
25
25
  });
26
26
  });
27
27
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
+ function normalizeQuerySet(values) {
29
+ if (!Array.isArray(values) || values.length === 0) return null;
30
+ const normalized = values.map(value => String(value ?? '').trim()).filter(Boolean);
31
+ return normalized.length ? new Set(normalized) : null;
32
+ }
33
+ function matchesAny(values, querySet) {
34
+ if (!querySet) return true;
35
+ return values.some(value => querySet.has(String(value ?? '').trim()));
36
+ }
28
37
  class ProductList extends _BaseModule.BaseModule {
29
38
  defaultName = 'productList';
30
39
  defaultVersion = '1.0.0';
@@ -281,10 +290,46 @@ class ProductList extends _BaseModule.BaseModule {
281
290
  const product = this.store.list.find(product => product.id === id);
282
291
  return product ? (0, _lodashEs.cloneDeep)(product) : undefined;
283
292
  }
293
+ async queryProducts(params = {}) {
294
+ const includeIds = normalizeQuerySet(params.includeIds);
295
+ const excludeIds = normalizeQuerySet(params.excludeIds);
296
+ const categoryIds = normalizeQuerySet(params.categoryIds);
297
+ const collectionIds = normalizeQuerySet(params.collectionIds);
298
+ const extensionTypes = normalizeQuerySet(params.extensionTypes);
299
+ const statuses = normalizeQuerySet(params.statuses);
300
+ const channelApplications = normalizeQuerySet(params.channelApplications);
301
+ const codeOrBarcode = typeof params.codeOrBarcode === 'string' ? params.codeOrBarcode.trim() : '';
302
+ const products = (this.store.list || []).filter(product => {
303
+ const productId = String(product.id ?? '').trim();
304
+ if (includeIds && !includeIds.has(productId)) return false;
305
+ if (excludeIds && excludeIds.has(productId)) return false;
306
+ if (categoryIds) {
307
+ const productCategoryIds = (product.categories || []).flatMap(category => [category?.id, category?.pivot?.product_category_id]);
308
+ if (!matchesAny(productCategoryIds, categoryIds)) return false;
309
+ }
310
+ if (collectionIds) {
311
+ const productCollectionIds = (product.collection || []).map(collection => collection?.id);
312
+ if (!matchesAny(productCollectionIds, collectionIds)) return false;
313
+ }
314
+ if (extensionTypes && !extensionTypes.has(String(product.extension_type ?? '').trim())) return false;
315
+ if (statuses && !statuses.has(String(product.status ?? '').trim())) return false;
316
+ if (channelApplications) {
317
+ if (!matchesAny(product.channel_application || [], channelApplications)) return false;
318
+ }
319
+ if (codeOrBarcode) {
320
+ const code = typeof product.code === 'string' ? product.code.trim() : '';
321
+ const barcode = typeof product.barcode === 'string' ? product.barcode.trim() : '';
322
+ if (code !== codeOrBarcode && barcode !== codeOrBarcode) return false;
323
+ }
324
+ return true;
325
+ });
326
+ return (0, _lodashEs.cloneDeep)(products);
327
+ }
284
328
  async getProductByIds(ids) {
285
329
  await this.core.effects.emit(`${this.name}:onGetProductByIds`, this.store.list);
286
- const products = this.store.list.filter(product => ids.includes(product.id));
287
- return products;
330
+ return this.queryProducts({
331
+ includeIds: ids
332
+ });
288
333
  }
289
334
  async addProduct(products) {
290
335
  // list 需要根据 id 去重
@@ -15,6 +15,16 @@ export interface ProductListLoadProductsParams {
15
15
  /** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
16
16
  strategy_context?: Record<string, any>;
17
17
  }
18
+ export interface ProductListStoreQueryParams {
19
+ includeIds?: Array<number | string>;
20
+ excludeIds?: Array<number | string>;
21
+ categoryIds?: Array<number | string>;
22
+ collectionIds?: Array<number | string>;
23
+ extensionTypes?: string[];
24
+ statuses?: ProductData['status'][];
25
+ channelApplications?: string[];
26
+ codeOrBarcode?: string;
27
+ }
18
28
  export interface ProductListData {
19
29
  list: ProductData[];
20
30
  selectProducts: ProductData[];
@@ -14,6 +14,11 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
14
14
  setRulesList(rulesList: Rules[]): Promise<void>;
15
15
  getRulesList(): Rules[];
16
16
  getWalletPassEvaluator(): import("../..").WalletPassEvaluator | undefined;
17
+ private normalizeHolderRecordIds;
18
+ /**
19
+ * 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
20
+ * required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
21
+ */
17
22
  private checkHolderMatch;
18
23
  isDiscountListAvailable({ oldDiscountList, newDiscountList, productList, orderTotalAmount, holders, isFormSubject, }: {
19
24
  oldDiscountList: Discount[];
@@ -38,21 +38,30 @@ class RulesModule extends _BaseModule.BaseModule {
38
38
  getWalletPassEvaluator() {
39
39
  return this.window.getWalletPassEvaluator?.();
40
40
  }
41
+ normalizeHolderRecordIds(value) {
42
+ const records = Array.isArray(value) ? value : [value];
43
+ return Array.from(new Set(records.map(record => {
44
+ if (record && typeof record === 'object') {
45
+ return record.form_record_id;
46
+ }
47
+ return record;
48
+ }).filter(record => record !== undefined && record !== null && record !== '' && record !== 0 && record !== '0').map(String)));
49
+ }
41
50
 
42
- // 商品不需要holder,则不需要判断,直接返回true,商品需要holder但是还没填写,那么暂时不使用带有holder的券,直到填写才去匹配
51
+ /**
52
+ * 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
53
+ * required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
54
+ */
43
55
  checkHolderMatch(discount, product, holders) {
44
56
  // 非表单类型 holder 视为匹配
45
57
  if (discount.holder?.holder_type !== 'form') return true;
46
- // 主预约holder, 目前(20251124)默认只考虑单个holder的情况
47
- // 旧版 holders[0].form_record_id 新版 holders[0]
48
- const orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id || holders[0] : undefined;
49
- const productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
50
- // 商品不需要选holder,则不对比holder,直接返回true,
51
- if (!product.isNeedHolder) return true;
52
- // 商品需要holder,但父预约及商品都无holder,返回false
53
- if (!orderHolderId && !productHolderId) return false;
54
- // 最终直接匹配 holder 是否相同
55
- return (productHolderId || orderHolderId) === discount.holder.holder_id;
58
+ const discountHolderIds = this.normalizeHolderRecordIds(discount.holder.holder_id);
59
+ if (!discountHolderIds.length) return false;
60
+ const productHolderIds = this.normalizeHolderRecordIds(product.holder_id);
61
+ const candidateHolderIds = productHolderIds.length ? productHolderIds : this.normalizeHolderRecordIds(holders);
62
+ if (!candidateHolderIds.length) return false;
63
+ const discountHolderIdSet = new Set(discountHolderIds);
64
+ return candidateHolderIds.some(holderId => discountHolderIdSet.has(holderId));
56
65
  }
57
66
 
58
67
  // 判断discountList 是否可以对当前productList生效
@@ -1119,7 +1128,8 @@ class RulesModule extends _BaseModule.BaseModule {
1119
1128
  processedFlatItemsMap.set(flatItem._id, [{
1120
1129
  ...flatItem,
1121
1130
  discount_list: isManualDiscount ? this.resolveDiscountListForManualOverride(flatItem.bundleItem?.discount_list || []) : this.filterDiscountListByType(flatItem.bundleItem?.discount_list || [], 'promotion'),
1122
- price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1131
+ price: flatItem.bundleItem.price,
1132
+ bundle_selling_price: flatItem.bundleItem.bundle_selling_price ?? (isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price),
1123
1133
  processed: true
1124
1134
  }]);
1125
1135
  }
@@ -30,6 +30,7 @@ export declare class SalesSummaryModule extends BaseModule implements Module, Sa
30
30
  taxRate?: number;
31
31
  shopDiscount?: string | number;
32
32
  channel?: string;
33
+ virtualSettlementMode?: boolean;
33
34
  }): Promise<{
34
35
  tax_title: string;
35
36
  tax_rate: number | undefined;
@@ -126,7 +126,8 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
126
126
  isPriceIncludeTax,
127
127
  taxRate,
128
128
  shopDiscount,
129
- channel
129
+ channel,
130
+ virtualSettlementMode = false
130
131
  } = params;
131
132
  const summaryChannel = channel || this.resolveChannel();
132
133
  if (summaryChannel !== this.surchargeListChannel) {
@@ -151,7 +152,8 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
151
152
  surchargeList: this.store.surchargeList,
152
153
  scheduleById,
153
154
  isInScheduleByDate: _Schedule.ScheduleModule.isInScheduleByDate,
154
- shopDiscount
155
+ shopDiscount,
156
+ virtualSettlementMode
155
157
  });
156
158
  const summaryWithTaxMeta = {
157
159
  ...summary,
@@ -64,5 +64,6 @@ export interface SalesSummaryModuleAPI {
64
64
  taxRate?: number;
65
65
  shopDiscount?: string | number;
66
66
  channel?: string;
67
+ virtualSettlementMode?: boolean;
67
68
  }): Promise<SalesSummaryData>;
68
69
  }
@@ -8,4 +8,5 @@ export declare function calculateSalesSummary(params: {
8
8
  scheduleById?: Record<string, any>;
9
9
  isInScheduleByDate?: any;
10
10
  shopDiscount?: string | number;
11
+ virtualSettlementMode?: boolean;
11
12
  }): SalesSummaryData;
@@ -837,11 +837,27 @@ function calculateSalesSummary(params) {
837
837
  surchargeList,
838
838
  scheduleById = {},
839
839
  isInScheduleByDate,
840
- shopDiscount
840
+ shopDiscount,
841
+ virtualSettlementMode = false
841
842
  } = params;
842
843
  if (!products?.length) return createEmptySalesSummary();
843
844
  const summaryProducts = products.filter(product => !isGeneratedVoucherProduct(product));
844
845
  if (!summaryProducts.length) return createEmptySalesSummary();
846
+ if (virtualSettlementMode) {
847
+ const productQuantity = summaryProducts.reduce((sum, item) => sum + getSafeNum(item.num), 0);
848
+ const productAmount = summaryProducts.reduce((sum, item) => sum.plus(toDecimal(item.selling_price).times(getSafeNum(item.num))), new _decimal.default(0));
849
+ const amount = toFixed2(productAmount);
850
+ return {
851
+ ...createEmptySalesSummary(),
852
+ product_quantity: productQuantity,
853
+ product_original_amount: amount,
854
+ product_amount: amount,
855
+ product_expect_amount: amount,
856
+ expect_amount: amount,
857
+ total_amount: amount,
858
+ is_price_include_tax: isPriceIncludeTax
859
+ };
860
+ }
845
861
  const productQuantity = summaryProducts.reduce((sum, item) => sum + getSafeNum(item.num), 0);
846
862
  const productOriginalAmount = summaryProducts.reduce((sum, item) => sum.plus(getUnitOriginalTotal(item).times(getSafeNum(item.num))), new _decimal.default(0));
847
863
  const productAmount = summaryProducts.reduce((sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))), new _decimal.default(0));
@@ -70,6 +70,7 @@ export interface RequestOptions {
70
70
  cache?: CacheProps;
71
71
  cacheUpdateChange?: (data: any) => void;
72
72
  osServer?: boolean;
73
+ isNocobase?: boolean;
73
74
  prefix?: boolean;
74
75
  callback?: (res: any) => void;
75
76
  subscriberId?: string;
@@ -125,7 +126,7 @@ declare class RequestPluginImpl implements RequestPlugin {
125
126
  /**
126
127
  * GET 请求
127
128
  */
128
- get<T = any>(url: string, options?: RequestOptions): Promise<T>;
129
+ get<T = any>(url: string, dataOrOptions?: any, options?: RequestOptions): Promise<T>;
129
130
  /**
130
131
  * POST 请求
131
132
  */