@pisell/pisellos 2.2.247 → 2.2.248

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.
@@ -0,0 +1,9 @@
1
+ // 导出评估器
2
+ export { PromotionEvaluator } from "./evaluator";
3
+
4
+ // 导出适配器
5
+ export { PromotionAdapter } from "./adapter";
6
+ export { default } from "./adapter";
7
+
8
+ // 导出策略配置示例常量
9
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
@@ -480,6 +480,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
480
480
  recalcOnHydrate?: boolean;
481
481
  }): Promise<OrderTempOrder>;
482
482
  private normalizeTempOrderForRuntime;
483
+ private hydrateLinkedBookingIdentity;
483
484
  private pickHydratedDisplayText;
484
485
  private formatHydratedNamePair;
485
486
  private buildHydratedProductOptionString;
@@ -445,7 +445,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
445
445
  value: function () {
446
446
  var _loadDiscountConfig = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(params) {
447
447
  var _this$store$tempOrder, _this$store$discount, _this$store$tempOrder2;
448
- var orderId, discountList, _this$store$discount2, _this$store$discount3, _this$store$discount4, currentEditDiscounts, currentEditDiscountIds, mergedDiscountList;
448
+ var orderId, discountList, _this$store$discount2, _this$store$discount3, _this$store$discount4, currentEditDiscounts, runtimeDiscountIds, runtimeDiscounts, mergedDiscountList;
449
449
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
450
450
  while (1) switch (_context3.prev = _context3.next) {
451
451
  case 0:
@@ -464,29 +464,30 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
464
464
  case 3:
465
465
  discountList = _context3.sent;
466
466
  if (!discountList) {
467
- _context3.next = 12;
467
+ _context3.next = 13;
468
468
  break;
469
469
  }
470
470
  currentEditDiscounts = (((_this$store$discount2 = this.store.discount) === null || _this$store$discount2 === void 0 ? void 0 : _this$store$discount2.getDiscountList()) || []).filter(function (discount) {
471
471
  return discount === null || discount === void 0 ? void 0 : discount.isEditMode;
472
472
  });
473
- currentEditDiscountIds = new Set(currentEditDiscounts.map(function (discount) {
474
- return discount === null || discount === void 0 ? void 0 : discount.id;
475
- }));
476
- mergedDiscountList = [].concat(_toConsumableArray(currentEditDiscounts), _toConsumableArray(discountList.filter(function (discount) {
477
- return !currentEditDiscountIds.has(discount === null || discount === void 0 ? void 0 : discount.id);
478
- })));
479
- _context3.next = 10;
473
+ runtimeDiscountIds = new Set();
474
+ runtimeDiscounts = discountList.filter(function (discount) {
475
+ if (runtimeDiscountIds.has(discount === null || discount === void 0 ? void 0 : discount.id)) return false;
476
+ runtimeDiscountIds.add(discount === null || discount === void 0 ? void 0 : discount.id);
477
+ return true;
478
+ });
479
+ mergedDiscountList = [].concat(_toConsumableArray(currentEditDiscounts), _toConsumableArray(runtimeDiscounts));
480
+ _context3.next = 11;
480
481
  return (_this$store$discount3 = this.store.discount) === null || _this$store$discount3 === void 0 ? void 0 : _this$store$discount3.setOriginalDiscountList(mergedDiscountList);
481
- case 10:
482
- _context3.next = 12;
482
+ case 11:
483
+ _context3.next = 13;
483
484
  return (_this$store$discount4 = this.store.discount) === null || _this$store$discount4 === void 0 ? void 0 : _this$store$discount4.setDiscountList(mergedDiscountList);
484
- case 12:
485
+ case 13:
485
486
  if (params.apply !== false && (_this$store$tempOrder2 = this.store.tempOrder) !== null && _this$store$tempOrder2 !== void 0 && (_this$store$tempOrder2 = _this$store$tempOrder2.products) !== null && _this$store$tempOrder2 !== void 0 && _this$store$tempOrder2.length) {
486
487
  this.applyDiscount();
487
488
  }
488
489
  return _context3.abrupt("return", this.getDiscountList());
489
- case 14:
490
+ case 15:
490
491
  case "end":
491
492
  return _context3.stop();
492
493
  }
@@ -5140,12 +5141,54 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5140
5141
  _iterator22.f();
5141
5142
  }
5142
5143
  tempOrderExtend.productsByUid = productsByUid;
5144
+ this.hydrateLinkedBookingIdentity(nextTempOrder);
5143
5145
  if ((options === null || options === void 0 ? void 0 : options.ensureIdentity) !== false) {
5144
5146
  this.ensureExternalSaleNumber(nextTempOrder);
5145
5147
  }
5146
5148
  nextTempOrder.vouchers = raw.vouchers || [];
5147
5149
  return nextTempOrder;
5148
5150
  }
5151
+ }, {
5152
+ key: "hydrateLinkedBookingIdentity",
5153
+ value: function hydrateLinkedBookingIdentity(tempOrder) {
5154
+ var bookingUidByProductUid = new Map();
5155
+ var productByUid = new Map();
5156
+ (tempOrder.products || []).forEach(function (product) {
5157
+ var _product$metadata9;
5158
+ var productUid = (product === null || product === void 0 || (_product$metadata9 = product.metadata) === null || _product$metadata9 === void 0 ? void 0 : _product$metadata9.unique_identification_number) || (product === null || product === void 0 ? void 0 : product.unique_identification_number);
5159
+ if (productUid !== undefined && productUid !== null && String(productUid) !== '') {
5160
+ productByUid.set(String(productUid), product);
5161
+ }
5162
+ });
5163
+ (tempOrder.bookings || []).forEach(function (booking) {
5164
+ var _matchedProduct$metad;
5165
+ if (!booking || _typeof(booking) !== 'object') return;
5166
+ if (!booking.metadata || _typeof(booking.metadata) !== 'object') {
5167
+ booking.metadata = {};
5168
+ }
5169
+ var productUid = booking.product_uid || booking.metadata.product_uid;
5170
+ if (productUid === undefined || productUid === null || String(productUid) === '') return;
5171
+ var matchedProduct = productByUid.get(String(productUid));
5172
+ var existedProductBookingUid = (matchedProduct === null || matchedProduct === void 0 ? void 0 : matchedProduct.booking_uid) || (matchedProduct === null || matchedProduct === void 0 || (_matchedProduct$metad = matchedProduct.metadata) === null || _matchedProduct$metad === void 0 ? void 0 : _matchedProduct$metad.booking_uid);
5173
+ // 客户端订单详情可能缺少 booking 自身 uid,这里补齐后才能反写到商品行。
5174
+ var bookingUid = String(booking.metadata.unique_identification_number || existedProductBookingUid || createUuidV4());
5175
+ booking.metadata.unique_identification_number = bookingUid;
5176
+ bookingUidByProductUid.set(String(productUid), bookingUid);
5177
+ });
5178
+ (tempOrder.products || []).forEach(function (product) {
5179
+ var _product$metadata10;
5180
+ var productUid = (product === null || product === void 0 || (_product$metadata10 = product.metadata) === null || _product$metadata10 === void 0 ? void 0 : _product$metadata10.unique_identification_number) || (product === null || product === void 0 ? void 0 : product.unique_identification_number);
5181
+ if (productUid === undefined || productUid === null || String(productUid) === '') return;
5182
+ var bookingUid = bookingUidByProductUid.get(String(productUid));
5183
+ if (!bookingUid) return;
5184
+ if (!product.metadata || _typeof(product.metadata) !== 'object') {
5185
+ product.metadata = {};
5186
+ }
5187
+ var linkedBookingUid = String(product.booking_uid || product.metadata.booking_uid || bookingUid);
5188
+ product.booking_uid = linkedBookingUid;
5189
+ product.metadata.booking_uid = linkedBookingUid;
5190
+ });
5191
+ }
5149
5192
  }, {
5150
5193
  key: "pickHydratedDisplayText",
5151
5194
  value: function pickHydratedDisplayText(value) {
@@ -5273,13 +5316,26 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5273
5316
  key: "populateSavedAmounts",
5274
5317
  value: function populateSavedAmounts(productList, discountList) {
5275
5318
  var savedMap = new Map();
5276
- var addDiscountAmount = function addDiscountAmount(discount, quantity) {
5319
+ var editModeSavedMap = new Map();
5320
+ var runtimeSavedMap = new Map();
5321
+ var editModeDiscountKeys = new Set((discountList || []).filter(function (discount) {
5322
+ return discount === null || discount === void 0 ? void 0 : discount.isEditMode;
5323
+ }).map(function (discount) {
5324
+ return discount === null || discount === void 0 ? void 0 : discount.id;
5325
+ }).filter(function (id) {
5326
+ return id !== undefined && id !== null;
5327
+ }));
5328
+ var addDiscountAmount = function addDiscountAmount(targetMap, discountKey, amount) {
5329
+ targetMap.set(discountKey, (targetMap.get(discountKey) || new Decimal(0)).plus(amount));
5330
+ };
5331
+ var addProductDiscountAmount = function addProductDiscountAmount(discount, quantity, isPersistedProduct) {
5277
5332
  var _discount$discount3, _discount$metadata;
5278
5333
  var discountKey = ((_discount$discount3 = discount.discount) === null || _discount$discount3 === void 0 ? void 0 : _discount$discount3.resource_id) || discount.id;
5279
5334
  if (discountKey == null) return;
5280
5335
  var qty = Number(quantity) || 1;
5281
5336
  var amount = new Decimal(discount.amount || 0).times(qty).plus(((_discount$metadata = discount.metadata) === null || _discount$metadata === void 0 ? void 0 : _discount$metadata.product_discount_difference) || 0);
5282
- savedMap.set(discountKey, (savedMap.get(discountKey) || new Decimal(0)).plus(amount));
5337
+ addDiscountAmount(savedMap, discountKey, amount);
5338
+ addDiscountAmount(isPersistedProduct || discount.order_discount_id != null ? editModeSavedMap : runtimeSavedMap, discountKey, amount);
5283
5339
  };
5284
5340
  var _iterator24 = _createForOfIteratorHelper(productList),
5285
5341
  _step24;
@@ -5287,12 +5343,13 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5287
5343
  for (_iterator24.s(); !(_step24 = _iterator24.n()).done;) {
5288
5344
  var product = _step24.value;
5289
5345
  var qty = product.num || 1;
5346
+ var isPersistedProduct = Boolean(product.order_detail_id || product.orderDetailId || product.booking_id);
5290
5347
  var _iterator26 = _createForOfIteratorHelper(product.discount_list || []),
5291
5348
  _step26;
5292
5349
  try {
5293
5350
  for (_iterator26.s(); !(_step26 = _iterator26.n()).done;) {
5294
5351
  var pd = _step26.value;
5295
- addDiscountAmount(pd, qty);
5352
+ addProductDiscountAmount(pd, qty, isPersistedProduct);
5296
5353
  }
5297
5354
  } catch (err) {
5298
5355
  _iterator26.e(err);
@@ -5305,13 +5362,14 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5305
5362
  for (_iterator27.s(); !(_step27 = _iterator27.n()).done;) {
5306
5363
  var _ref75, _bundle$num3;
5307
5364
  var bundle = _step27.value;
5365
+ var isPersistedBundleProduct = isPersistedProduct || Boolean((bundle === null || bundle === void 0 ? void 0 : bundle.order_detail_id) || (bundle === null || bundle === void 0 ? void 0 : bundle.orderDetailId) || (bundle === null || bundle === void 0 ? void 0 : bundle.booking_id));
5308
5366
  var bundleQty = new Decimal(Number(qty) || 1).times(Number((_ref75 = (_bundle$num3 = bundle === null || bundle === void 0 ? void 0 : bundle.num) !== null && _bundle$num3 !== void 0 ? _bundle$num3 : bundle === null || bundle === void 0 ? void 0 : bundle.quantity) !== null && _ref75 !== void 0 ? _ref75 : 1) || 1).toNumber();
5309
5367
  var _iterator28 = _createForOfIteratorHelper((bundle === null || bundle === void 0 ? void 0 : bundle.discount_list) || []),
5310
5368
  _step28;
5311
5369
  try {
5312
5370
  for (_iterator28.s(); !(_step28 = _iterator28.n()).done;) {
5313
5371
  var _pd = _step28.value;
5314
- addDiscountAmount(_pd, bundleQty);
5372
+ addProductDiscountAmount(_pd, bundleQty, isPersistedBundleProduct);
5315
5373
  }
5316
5374
  } catch (err) {
5317
5375
  _iterator28.e(err);
@@ -5336,7 +5394,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5336
5394
  for (_iterator25.s(); !(_step25 = _iterator25.n()).done;) {
5337
5395
  var d = _step25.value;
5338
5396
  var key = d.id;
5339
- d.savedAmount = d.isSelected && key != null && savedMap.has(key) ? savedMap.get(key).toNumber() : 0;
5397
+ var sourceMap = d.isEditMode ? editModeSavedMap : editModeDiscountKeys.has(key) ? runtimeSavedMap : savedMap;
5398
+ d.savedAmount = d.isSelected && key != null && sourceMap.has(key) ? sourceMap.get(key).toNumber() : 0;
5340
5399
  }
5341
5400
  } catch (err) {
5342
5401
  _iterator25.e(err);
@@ -1,13 +1,13 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
4
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
1
5
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
6
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
3
8
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
4
9
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
5
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
10
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
11
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
12
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
13
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -40,7 +40,9 @@ var LABELS = {
40
40
  orderDiscount: 'Order discount',
41
41
  manualDiscount: 'Manual discount',
42
42
  payProcessingFee: 'Pay processing fee',
43
- rounding: 'Rounding'
43
+ rounding: 'Rounding',
44
+ gross: 'Gross',
45
+ tare: 'Tare'
44
46
  },
45
47
  zh_CN: {
46
48
  contactName: '联系人姓名',
@@ -64,7 +66,9 @@ var LABELS = {
64
66
  orderDiscount: '整单折扣',
65
67
  manualDiscount: '手动折扣',
66
68
  payProcessingFee: '支付手续费',
67
- rounding: '抹零'
69
+ rounding: '抹零',
70
+ gross: '重量',
71
+ tare: '去皮'
68
72
  },
69
73
  zh_HK: {
70
74
  contactName: '聯絡人姓名',
@@ -88,7 +92,9 @@ var LABELS = {
88
92
  orderDiscount: '整單折扣',
89
93
  manualDiscount: '手動折扣',
90
94
  payProcessingFee: '支付手續費',
91
- rounding: '抹零'
95
+ rounding: '抹零',
96
+ gross: '重量',
97
+ tare: '去皮'
92
98
  }
93
99
  };
94
100
  export function buildSmallTicketData(params) {
@@ -200,10 +206,18 @@ function buildProducts(order, locale, productMap) {
200
206
  parentProduct: parentProduct,
201
207
  locale: locale
202
208
  });
209
+ var extensionList = buildProductExtensionList({
210
+ product: product,
211
+ locale: locale,
212
+ currencySymbol: currencySymbol,
213
+ quantity: quantity,
214
+ originalPrice: originalPrice
215
+ });
203
216
  var discountList = normalizeProductDiscounts({
204
217
  product: product,
205
218
  locale: locale,
206
- currencySymbol: currencySymbol
219
+ currencySymbol: currencySymbol,
220
+ quantity: quantity
207
221
  });
208
222
  return _objectSpread(_objectSpread(_objectSpread(_objectSpread({
209
223
  product_title: productTitle,
@@ -211,7 +225,7 @@ function buildProducts(order, locale, productMap) {
211
225
  selling_price: formatMoney(sellingPrice, currencySymbol),
212
226
  original_price: formatMoney(originalPrice, currencySymbol),
213
227
  total_original_price: formatMoney(new Decimal(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
214
- extension_list: Array.isArray(product.extension_list) ? product.extension_list : []
228
+ extension_list: extensionList
215
229
  }, discountList.length ? {
216
230
  discount_list: discountList
217
231
  } : {}), options.length ? {
@@ -228,12 +242,13 @@ function buildProducts(order, locale, productMap) {
228
242
  function normalizeProductDiscounts(params) {
229
243
  var product = params.product,
230
244
  locale = params.locale,
231
- currencySymbol = params.currencySymbol;
245
+ currencySymbol = params.currencySymbol,
246
+ quantity = params.quantity;
232
247
  return normalizeArray(product.discount_list).map(function (discount) {
233
248
  var _ref8, _discount$amount;
234
- var title = resolveDiscountTitle(discount, locale);
249
+ var title = resolveDiscountTitleWithPercent(discount, locale);
235
250
  var amount = (_ref8 = (_discount$amount = discount.amount) !== null && _discount$amount !== void 0 ? _discount$amount : discount.value) !== null && _ref8 !== void 0 ? _ref8 : discount.discount_amount;
236
- var formattedAmount = formatNegativeMoney(amount, currencySymbol);
251
+ var formattedAmount = formatNegativeMoney(new Decimal(toMoneyNumber(amount)).mul(quantity), currencySymbol);
237
252
  return _objectSpread(_objectSpread({}, discount), {}, {
238
253
  item: title,
239
254
  name: title,
@@ -242,9 +257,77 @@ function normalizeProductDiscounts(params) {
242
257
  });
243
258
  });
244
259
  }
260
+ function buildProductExtensionList(params) {
261
+ var product = params.product,
262
+ locale = params.locale,
263
+ currencySymbol = params.currencySymbol,
264
+ quantity = params.quantity,
265
+ originalPrice = params.originalPrice;
266
+ var extensionList = [].concat(_toConsumableArray(buildProductOpenWeightRows({
267
+ product: product,
268
+ locale: locale,
269
+ currencySymbol: currencySymbol
270
+ })), _toConsumableArray(quantity > 1 ? [{
271
+ item: buildProductQuantityPriceText({
272
+ quantity: quantity,
273
+ currencySymbol: currencySymbol,
274
+ price: originalPrice
275
+ }),
276
+ value: ''
277
+ }] : []));
278
+ return extensionList.length ? extensionList : normalizeArray(product.extension_list);
279
+ }
280
+ function buildProductOpenWeightRows(params) {
281
+ var _productSku$unit, _productSku$net_weigh, _productSku$unit_pric;
282
+ var product = params.product,
283
+ locale = params.locale,
284
+ currencySymbol = params.currencySymbol;
285
+ var productSku = product.product_sku || {};
286
+ if (productSku.open_sold_weight != 1) return [];
287
+ var unit = (_productSku$unit = productSku.unit) !== null && _productSku$unit !== void 0 ? _productSku$unit : '';
288
+ var manualFlag = productSku.weight_source === 'manual' ? '(M) ' : '';
289
+ var hasTare = toNumber(productSku.tare_weight, 0) > 0;
290
+ var rows = [];
291
+ if (hasTare) {
292
+ var _productSku$weight;
293
+ rows.push({
294
+ item: "".concat(manualFlag).concat(label(locale, 'gross'), ": ").concat((_productSku$weight = productSku.weight) !== null && _productSku$weight !== void 0 ? _productSku$weight : 0).concat(unit),
295
+ value: ''
296
+ });
297
+ rows.push({
298
+ item: "".concat(label(locale, 'tare'), ": ").concat(productSku.tare_weight).concat(unit),
299
+ value: ''
300
+ });
301
+ }
302
+ var netWeight = (_productSku$net_weigh = productSku.net_weight) !== null && _productSku$net_weigh !== void 0 ? _productSku$net_weigh : 0;
303
+ var unitPrice = (_productSku$unit_pric = productSku.unit_price) !== null && _productSku$unit_pric !== void 0 ? _productSku$unit_pric : 0;
304
+ var netItem = "".concat(netWeight, " ").concat(unit, " NET @ ").concat(currencySymbol).concat(unitPrice, "/").concat(unit);
305
+ rows.push({
306
+ item: hasTare ? netItem : "".concat(manualFlag).concat(netItem),
307
+ value: ''
308
+ });
309
+ return rows;
310
+ }
311
+ function buildProductQuantityPriceText(params) {
312
+ var quantity = params.quantity,
313
+ currencySymbol = params.currencySymbol,
314
+ price = params.price;
315
+ return "".concat(quantity, " @ ").concat(currencySymbol).concat(stringify(price), " EACH");
316
+ }
317
+ function resolveDiscountTitleWithPercent(discount, locale) {
318
+ var _discount$discount, _discount$discount$di, _discount$discount2;
319
+ var title = resolveDiscountTitle(discount, locale);
320
+ var percentRaw = (_discount$discount = discount.discount) === null || _discount$discount === void 0 ? void 0 : _discount$discount.percent;
321
+ var cardType = (_discount$discount$di = (_discount$discount2 = discount.discount) === null || _discount$discount2 === void 0 ? void 0 : _discount$discount2.discount_card_type) !== null && _discount$discount$di !== void 0 ? _discount$discount$di : 'percent';
322
+ var percent = percentRaw !== undefined && percentRaw !== null ? Math.trunc(Number(percentRaw)) : NaN;
323
+ if (percentRaw === undefined || percentRaw === null) return title;
324
+ if (cardType !== 'percent') return title;
325
+ if (Number.isNaN(percent)) return title;
326
+ return "".concat(title, " (").concat(percent, "%)");
327
+ }
245
328
  function resolveDiscountTitle(discount, locale) {
246
- var _ref9, _ref10, _ref11, _ref12, _discount$discount$na, _discount$discount, _discount$discount2, _discount$discount3;
247
- var title = getLocalizedValue((_ref9 = (_ref10 = (_ref11 = (_ref12 = (_discount$discount$na = (_discount$discount = discount.discount) === null || _discount$discount === void 0 ? void 0 : _discount$discount.name) !== null && _discount$discount$na !== void 0 ? _discount$discount$na : (_discount$discount2 = discount.discount) === null || _discount$discount2 === void 0 ? void 0 : _discount$discount2.title) !== null && _ref12 !== void 0 ? _ref12 : (_discount$discount3 = discount.discount) === null || _discount$discount3 === void 0 ? void 0 : _discount$discount3.message) !== null && _ref11 !== void 0 ? _ref11 : discount.name) !== null && _ref10 !== void 0 ? _ref10 : discount.title) !== null && _ref9 !== void 0 ? _ref9 : discount.message, locale);
329
+ var _ref9, _ref10, _ref11, _ref12, _discount$discount$na, _discount$discount3, _discount$discount4, _discount$discount5;
330
+ var title = getLocalizedValue((_ref9 = (_ref10 = (_ref11 = (_ref12 = (_discount$discount$na = (_discount$discount3 = discount.discount) === null || _discount$discount3 === void 0 ? void 0 : _discount$discount3.name) !== null && _discount$discount$na !== void 0 ? _discount$discount$na : (_discount$discount4 = discount.discount) === null || _discount$discount4 === void 0 ? void 0 : _discount$discount4.title) !== null && _ref12 !== void 0 ? _ref12 : (_discount$discount5 = discount.discount) === null || _discount$discount5 === void 0 ? void 0 : _discount$discount5.message) !== null && _ref11 !== void 0 ? _ref11 : discount.name) !== null && _ref10 !== void 0 ? _ref10 : discount.title) !== null && _ref9 !== void 0 ? _ref9 : discount.message, locale);
248
331
  if (title) return title;
249
332
  if (discount.type === 'product') return label(locale, 'manualDiscount');
250
333
  return '';
@@ -544,7 +627,7 @@ function formatBundlePrice(bundle, currencySymbol) {
544
627
  return formatMoney(amount, currencySymbol);
545
628
  }
546
629
  function buildFees(params) {
547
- var _ref36, _order$shop_discount;
630
+ var _ref36, _order$shop_discount, _ref37, _summary$product_orig;
548
631
  var order = params.order,
549
632
  shopInfo = params.shopInfo,
550
633
  locale = params.locale,
@@ -590,11 +673,14 @@ function buildFees(params) {
590
673
  value: formatMoney(payProcessingFee, currencySymbol)
591
674
  });
592
675
  }
676
+ var productExpectAmount = summary.product_expect_amount || summary.product_amount || order.product_expect_amount;
677
+ var productOriginalAmount = (_ref37 = (_summary$product_orig = summary.product_original_amount) !== null && _summary$product_orig !== void 0 ? _summary$product_orig : order.product_original_amount) !== null && _ref37 !== void 0 ? _ref37 : productExpectAmount;
678
+ var totalSavingsAmount = new Decimal(toMoneyNumber(productOriginalAmount)).minus(toMoneyNumber(productExpectAmount)).plus(toMoneyNumber(discountAmount));
593
679
  return {
594
680
  fees: fees,
595
681
  countFee: _objectSpread(_objectSpread(_objectSpread(_objectSpread({
596
682
  total_amount: formatMoney(summary.total_amount || order.total_amount, currencySymbol),
597
- product_expect_amount: formatMoney(summary.product_expect_amount || summary.product_amount || order.product_expect_amount, currencySymbol),
683
+ product_expect_amount: formatMoney(productExpectAmount, currencySymbol),
598
684
  expect_amount: formatMoney(summary.expect_amount || order.expect_amount || summary.total_amount || order.total_amount, currencySymbol),
599
685
  product_quantity: toNumber(summary.product_quantity || products.reduce(function (sum, product) {
600
686
  return sum + product.product_quantity;
@@ -605,8 +691,8 @@ function buildFees(params) {
605
691
  total_refund_amount: formatMoney(summary.total_refund_amount || order.total_refund_amount, currencySymbol)
606
692
  }, isNonZero(roundingAmount) ? {
607
693
  rounding_amount: formatMoney(roundingAmount, currencySymbol)
608
- } : {}), isNonZero(discountAmount) ? {
609
- order_total_discount: formatMoney(discountAmount, currencySymbol)
694
+ } : {}), isNonZero(totalSavingsAmount) ? {
695
+ order_total_discount: formatMoney(totalSavingsAmount, currencySymbol)
610
696
  } : {}), isNonZero(payProcessingFee) ? {
611
697
  pay_processing_fee: formatMoney(payProcessingFee, currencySymbol)
612
698
  } : {}), isNonZero(taxFee) ? {
@@ -690,8 +776,8 @@ function buildPaymentData(params) {
690
776
  currencySymbol: params.currencySymbol
691
777
  })));
692
778
  } else {
693
- var _ref37, _payment$remaining_am, _payment$metadata;
694
- var remainingAmount = (_ref37 = (_payment$remaining_am = payment.remaining_amount) !== null && _payment$remaining_am !== void 0 ? _payment$remaining_am : payment.balance) !== null && _ref37 !== void 0 ? _ref37 : (_payment$metadata = payment.metadata) === null || _payment$metadata === void 0 ? void 0 : _payment$metadata.remaining_amount;
779
+ var _ref38, _payment$remaining_am, _payment$metadata;
780
+ var remainingAmount = (_ref38 = (_payment$remaining_am = payment.remaining_amount) !== null && _payment$remaining_am !== void 0 ? _payment$remaining_am : payment.balance) !== null && _ref38 !== void 0 ? _ref38 : (_payment$metadata = payment.metadata) === null || _payment$metadata === void 0 ? void 0 : _payment$metadata.remaining_amount;
695
781
  if (remainingAmount !== undefined && remainingAmount !== null) {
696
782
  items.push({
697
783
  item: label(params.locale, 'remainingAmount'),
@@ -799,12 +885,12 @@ function label(locale, key) {
799
885
  return ((_LABELS$locale = LABELS[locale]) === null || _LABELS$locale === void 0 ? void 0 : _LABELS$locale[key]) || LABELS.en[key] || key;
800
886
  }
801
887
  function getLocalizedValue(value, locale) {
802
- var _ref38, _ref39, _ref40, _ref41, _ref42, _ref43, _value$locale2;
888
+ var _ref39, _ref40, _ref41, _ref42, _ref43, _ref44, _value$locale2;
803
889
  if (value === undefined || value === null) return '';
804
890
  if (_typeof(value) !== 'object') return stringify(value);
805
891
  var dashedLocale = locale.replace('_', '-');
806
892
  var underscoredLocale = locale.replace('-', '_');
807
- return stringify((_ref38 = (_ref39 = (_ref40 = (_ref41 = (_ref42 = (_ref43 = (_value$locale2 = value[locale]) !== null && _value$locale2 !== void 0 ? _value$locale2 : value[dashedLocale]) !== null && _ref43 !== void 0 ? _ref43 : value[underscoredLocale]) !== null && _ref42 !== void 0 ? _ref42 : value.original) !== null && _ref41 !== void 0 ? _ref41 : value.auto) !== null && _ref40 !== void 0 ? _ref40 : value.default) !== null && _ref39 !== void 0 ? _ref39 : value.en) !== null && _ref38 !== void 0 ? _ref38 : '');
893
+ return stringify((_ref39 = (_ref40 = (_ref41 = (_ref42 = (_ref43 = (_ref44 = (_value$locale2 = value[locale]) !== null && _value$locale2 !== void 0 ? _value$locale2 : value[dashedLocale]) !== null && _ref44 !== void 0 ? _ref44 : value[underscoredLocale]) !== null && _ref43 !== void 0 ? _ref43 : value.original) !== null && _ref42 !== void 0 ? _ref42 : value.auto) !== null && _ref41 !== void 0 ? _ref41 : value.default) !== null && _ref40 !== void 0 ? _ref40 : value.en) !== null && _ref39 !== void 0 ? _ref39 : '');
808
894
  }
809
895
  function serviceTypeToLabelKey(serviceType) {
810
896
  var normalized = serviceType.toLowerCase();
@@ -63,6 +63,9 @@ function preserveManualProductDiscountProducts(previousProducts, nextProducts) {
63
63
  return previous && isBaseSalesManualProductDiscountProduct(previous) ? previous : product;
64
64
  });
65
65
  }
66
+ function isBaseSalesHistoricalDiscountEntry(discount) {
67
+ return Boolean((discount === null || discount === void 0 ? void 0 : discount.isEditMode) || (discount === null || discount === void 0 ? void 0 : discount.isDisabled) || (discount === null || discount === void 0 ? void 0 : discount.order_discount_id) != null);
68
+ }
66
69
  function getBaseSalesUniqueArrayMetadataKey(key) {
67
70
  if (key === 'products' || key === 'bookings') return 'unique_identification_number';
68
71
  if (key === 'payments' || key === 'payment') return 'unique_payment_number';
@@ -1322,7 +1325,8 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
1322
1325
  return discount.id;
1323
1326
  }));
1324
1327
  return [].concat(_toConsumableArray(historyDiscountList), _toConsumableArray((discountList || []).filter(function (discount) {
1325
- return !historyIds.has(discount.id);
1328
+ if (!historyIds.has(discount.id)) return true;
1329
+ return !isBaseSalesHistoricalDiscountEntry(discount);
1326
1330
  })));
1327
1331
  }
1328
1332
  }, {
@@ -1347,11 +1351,12 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
1347
1351
  key: "mergeCurrentDiscountSelectionState",
1348
1352
  value: function mergeCurrentDiscountSelectionState(discountList, currentDiscountList) {
1349
1353
  if (!currentDiscountList.length) return discountList;
1350
- var currentDiscountMap = new Map(currentDiscountList.map(function (discount) {
1351
- return [discount.id, discount];
1352
- }));
1354
+ var currentDiscountMap = new Map();
1355
+ currentDiscountList.forEach(function (discount) {
1356
+ currentDiscountMap.set("".concat(discount.id, ":").concat(isBaseSalesHistoricalDiscountEntry(discount) ? 'historical' : 'runtime'), discount);
1357
+ });
1353
1358
  return discountList.map(function (discount) {
1354
- var currentDiscount = currentDiscountMap.get(discount.id);
1359
+ var currentDiscount = currentDiscountMap.get("".concat(discount.id, ":").concat(isBaseSalesHistoricalDiscountEntry(discount) ? 'historical' : 'runtime'));
1355
1360
  if (!currentDiscount) return discount;
1356
1361
  if (currentDiscount.isManualSelect) {
1357
1362
  return _objectSpread(_objectSpread({}, discount), {}, {
@@ -1731,7 +1736,7 @@ export var BaseSalesImpl = /*#__PURE__*/function (_BaseModule) {
1731
1736
  case 3:
1732
1737
  list = this.store.order.getDiscountList();
1733
1738
  updated = list.map(function (d) {
1734
- return d.id === params.discountId ? _objectSpread(_objectSpread({}, d), {}, {
1739
+ return d.id === params.discountId && !isBaseSalesHistoricalDiscountEntry(d) ? _objectSpread(_objectSpread({}, d), {}, {
1735
1740
  isSelected: params.isSelected,
1736
1741
  isManualSelect: !params.isSelected
1737
1742
  }) : d;
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 5 | 1 | 4 | 2 | 3 | 6;
314
+ weekNum: 0 | 2 | 1 | 6 | 3 | 4 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -480,6 +480,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
480
480
  recalcOnHydrate?: boolean;
481
481
  }): Promise<OrderTempOrder>;
482
482
  private normalizeTempOrderForRuntime;
483
+ private hydrateLinkedBookingIdentity;
483
484
  private pickHydratedDisplayText;
484
485
  private formatHydratedNamePair;
485
486
  private buildHydratedProductOptionString;
@@ -168,33 +168,53 @@ var OrderModule = class extends import_BaseModule.BaseModule {
168
168
  */
169
169
  static populateSavedAmounts(productList, discountList) {
170
170
  const savedMap = /* @__PURE__ */ new Map();
171
- const addDiscountAmount = (discount, quantity) => {
171
+ const editModeSavedMap = /* @__PURE__ */ new Map();
172
+ const runtimeSavedMap = /* @__PURE__ */ new Map();
173
+ const editModeDiscountKeys = new Set(
174
+ (discountList || []).filter((discount) => discount == null ? void 0 : discount.isEditMode).map((discount) => discount == null ? void 0 : discount.id).filter((id) => id !== void 0 && id !== null)
175
+ );
176
+ const addDiscountAmount = (targetMap, discountKey, amount) => {
177
+ targetMap.set(
178
+ discountKey,
179
+ (targetMap.get(discountKey) || new import_decimal.default(0)).plus(amount)
180
+ );
181
+ };
182
+ const addProductDiscountAmount = (discount, quantity, isPersistedProduct) => {
172
183
  var _a, _b;
173
184
  const discountKey = ((_a = discount.discount) == null ? void 0 : _a.resource_id) || discount.id;
174
185
  if (discountKey == null)
175
186
  return;
176
187
  const qty = Number(quantity) || 1;
177
188
  const amount = new import_decimal.default(discount.amount || 0).times(qty).plus(((_b = discount.metadata) == null ? void 0 : _b.product_discount_difference) || 0);
178
- savedMap.set(
189
+ addDiscountAmount(savedMap, discountKey, amount);
190
+ addDiscountAmount(
191
+ isPersistedProduct || discount.order_discount_id != null ? editModeSavedMap : runtimeSavedMap,
179
192
  discountKey,
180
- (savedMap.get(discountKey) || new import_decimal.default(0)).plus(amount)
193
+ amount
181
194
  );
182
195
  };
183
196
  for (const product of productList) {
184
197
  const qty = product.num || 1;
198
+ const isPersistedProduct = Boolean(
199
+ product.order_detail_id || product.orderDetailId || product.booking_id
200
+ );
185
201
  for (const pd of product.discount_list || []) {
186
- addDiscountAmount(pd, qty);
202
+ addProductDiscountAmount(pd, qty, isPersistedProduct);
187
203
  }
188
204
  for (const bundle of product.product_bundle || []) {
205
+ const isPersistedBundleProduct = isPersistedProduct || Boolean(
206
+ (bundle == null ? void 0 : bundle.order_detail_id) || (bundle == null ? void 0 : bundle.orderDetailId) || (bundle == null ? void 0 : bundle.booking_id)
207
+ );
189
208
  const bundleQty = new import_decimal.default(Number(qty) || 1).times(Number((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity) ?? 1) || 1).toNumber();
190
209
  for (const pd of (bundle == null ? void 0 : bundle.discount_list) || []) {
191
- addDiscountAmount(pd, bundleQty);
210
+ addProductDiscountAmount(pd, bundleQty, isPersistedBundleProduct);
192
211
  }
193
212
  }
194
213
  }
195
214
  for (const d of discountList) {
196
215
  const key = d.id;
197
- d.savedAmount = d.isSelected && key != null && savedMap.has(key) ? savedMap.get(key).toNumber() : 0;
216
+ const sourceMap = d.isEditMode ? editModeSavedMap : editModeDiscountKeys.has(key) ? runtimeSavedMap : savedMap;
217
+ d.savedAmount = d.isSelected && key != null && sourceMap.has(key) ? sourceMap.get(key).toNumber() : 0;
198
218
  }
199
219
  }
200
220
  applyProductDiscountPrices(products) {
@@ -371,12 +391,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
371
391
  }));
372
392
  if (discountList) {
373
393
  const currentEditDiscounts = (((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || []).filter((discount) => discount == null ? void 0 : discount.isEditMode);
374
- const currentEditDiscountIds = new Set(
375
- currentEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
376
- );
394
+ const runtimeDiscountIds = /* @__PURE__ */ new Set();
395
+ const runtimeDiscounts = discountList.filter((discount) => {
396
+ if (runtimeDiscountIds.has(discount == null ? void 0 : discount.id))
397
+ return false;
398
+ runtimeDiscountIds.add(discount == null ? void 0 : discount.id);
399
+ return true;
400
+ });
377
401
  const mergedDiscountList = [
378
402
  ...currentEditDiscounts,
379
- ...discountList.filter((discount) => !currentEditDiscountIds.has(discount == null ? void 0 : discount.id))
403
+ ...runtimeDiscounts
380
404
  ];
381
405
  await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(mergedDiscountList));
382
406
  await ((_e = this.store.discount) == null ? void 0 : _e.setDiscountList(mergedDiscountList));
@@ -3670,12 +3694,59 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3670
3694
  };
3671
3695
  }
3672
3696
  tempOrderExtend.productsByUid = productsByUid;
3697
+ this.hydrateLinkedBookingIdentity(nextTempOrder);
3673
3698
  if ((options == null ? void 0 : options.ensureIdentity) !== false) {
3674
3699
  this.ensureExternalSaleNumber(nextTempOrder);
3675
3700
  }
3676
3701
  nextTempOrder.vouchers = raw.vouchers || [];
3677
3702
  return nextTempOrder;
3678
3703
  }
3704
+ hydrateLinkedBookingIdentity(tempOrder) {
3705
+ const bookingUidByProductUid = /* @__PURE__ */ new Map();
3706
+ const productByUid = /* @__PURE__ */ new Map();
3707
+ (tempOrder.products || []).forEach((product) => {
3708
+ var _a;
3709
+ const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
3710
+ if (productUid !== void 0 && productUid !== null && String(productUid) !== "") {
3711
+ productByUid.set(String(productUid), product);
3712
+ }
3713
+ });
3714
+ (tempOrder.bookings || []).forEach((booking) => {
3715
+ var _a;
3716
+ if (!booking || typeof booking !== "object")
3717
+ return;
3718
+ if (!booking.metadata || typeof booking.metadata !== "object") {
3719
+ booking.metadata = {};
3720
+ }
3721
+ const productUid = booking.product_uid || booking.metadata.product_uid;
3722
+ if (productUid === void 0 || productUid === null || String(productUid) === "")
3723
+ return;
3724
+ const matchedProduct = productByUid.get(String(productUid));
3725
+ const existedProductBookingUid = (matchedProduct == null ? void 0 : matchedProduct.booking_uid) || ((_a = matchedProduct == null ? void 0 : matchedProduct.metadata) == null ? void 0 : _a.booking_uid);
3726
+ const bookingUid = String(
3727
+ booking.metadata.unique_identification_number || existedProductBookingUid || (0, import_utils.createUuidV4)()
3728
+ );
3729
+ booking.metadata.unique_identification_number = bookingUid;
3730
+ bookingUidByProductUid.set(String(productUid), bookingUid);
3731
+ });
3732
+ (tempOrder.products || []).forEach((product) => {
3733
+ var _a;
3734
+ const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
3735
+ if (productUid === void 0 || productUid === null || String(productUid) === "")
3736
+ return;
3737
+ const bookingUid = bookingUidByProductUid.get(String(productUid));
3738
+ if (!bookingUid)
3739
+ return;
3740
+ if (!product.metadata || typeof product.metadata !== "object") {
3741
+ product.metadata = {};
3742
+ }
3743
+ const linkedBookingUid = String(
3744
+ product.booking_uid || product.metadata.booking_uid || bookingUid
3745
+ );
3746
+ product.booking_uid = linkedBookingUid;
3747
+ product.metadata.booking_uid = linkedBookingUid;
3748
+ });
3749
+ }
3679
3750
  pickHydratedDisplayText(value) {
3680
3751
  if (value === void 0 || value === null)
3681
3752
  return "";
@@ -59,7 +59,9 @@ var LABELS = {
59
59
  orderDiscount: "Order discount",
60
60
  manualDiscount: "Manual discount",
61
61
  payProcessingFee: "Pay processing fee",
62
- rounding: "Rounding"
62
+ rounding: "Rounding",
63
+ gross: "Gross",
64
+ tare: "Tare"
63
65
  },
64
66
  zh_CN: {
65
67
  contactName: "联系人姓名",
@@ -83,7 +85,9 @@ var LABELS = {
83
85
  orderDiscount: "整单折扣",
84
86
  manualDiscount: "手动折扣",
85
87
  payProcessingFee: "支付手续费",
86
- rounding: "抹零"
88
+ rounding: "抹零",
89
+ gross: "重量",
90
+ tare: "去皮"
87
91
  },
88
92
  zh_HK: {
89
93
  contactName: "聯絡人姓名",
@@ -107,7 +111,9 @@ var LABELS = {
107
111
  orderDiscount: "整單折扣",
108
112
  manualDiscount: "手動折扣",
109
113
  payProcessingFee: "支付手續費",
110
- rounding: "抹零"
114
+ rounding: "抹零",
115
+ gross: "重量",
116
+ tare: "去皮"
111
117
  }
112
118
  };
113
119
  function buildSmallTicketData(params) {
@@ -187,14 +193,21 @@ function buildProducts(order, locale, productMap) {
187
193
  parentProduct
188
194
  });
189
195
  const resolvedVariant = resolveProductVariantText({ product, parentProduct, locale });
190
- const discountList = normalizeProductDiscounts({ product, locale, currencySymbol });
196
+ const extensionList = buildProductExtensionList({
197
+ product,
198
+ locale,
199
+ currencySymbol,
200
+ quantity,
201
+ originalPrice
202
+ });
203
+ const discountList = normalizeProductDiscounts({ product, locale, currencySymbol, quantity });
191
204
  return {
192
205
  product_title: productTitle,
193
206
  product_quantity: quantity,
194
207
  selling_price: formatMoney(sellingPrice, currencySymbol),
195
208
  original_price: formatMoney(originalPrice, currencySymbol),
196
209
  total_original_price: formatMoney(new import_decimal.default(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
197
- extension_list: Array.isArray(product.extension_list) ? product.extension_list : [],
210
+ extension_list: extensionList,
198
211
  ...discountList.length ? { discount_list: discountList } : {},
199
212
  ...options.length ? { options } : {},
200
213
  ...resolvedVariant ? { variant: resolvedVariant } : {},
@@ -203,11 +216,11 @@ function buildProducts(order, locale, productMap) {
203
216
  });
204
217
  }
205
218
  function normalizeProductDiscounts(params) {
206
- const { product, locale, currencySymbol } = params;
219
+ const { product, locale, currencySymbol, quantity } = params;
207
220
  return normalizeArray(product.discount_list).map((discount) => {
208
- const title = resolveDiscountTitle(discount, locale);
221
+ const title = resolveDiscountTitleWithPercent(discount, locale);
209
222
  const amount = discount.amount ?? discount.value ?? discount.discount_amount;
210
- const formattedAmount = formatNegativeMoney(amount, currencySymbol);
223
+ const formattedAmount = formatNegativeMoney(new import_decimal.default(toMoneyNumber(amount)).mul(quantity), currencySymbol);
211
224
  return {
212
225
  ...discount,
213
226
  item: title,
@@ -217,6 +230,63 @@ function normalizeProductDiscounts(params) {
217
230
  };
218
231
  });
219
232
  }
233
+ function buildProductExtensionList(params) {
234
+ const { product, locale, currencySymbol, quantity, originalPrice } = params;
235
+ const extensionList = [
236
+ ...buildProductOpenWeightRows({ product, locale, currencySymbol }),
237
+ ...quantity > 1 ? [{
238
+ item: buildProductQuantityPriceText({ quantity, currencySymbol, price: originalPrice }),
239
+ value: ""
240
+ }] : []
241
+ ];
242
+ return extensionList.length ? extensionList : normalizeArray(product.extension_list);
243
+ }
244
+ function buildProductOpenWeightRows(params) {
245
+ const { product, locale, currencySymbol } = params;
246
+ const productSku = product.product_sku || {};
247
+ if (productSku.open_sold_weight != 1)
248
+ return [];
249
+ const unit = productSku.unit ?? "";
250
+ const manualFlag = productSku.weight_source === "manual" ? "(M) " : "";
251
+ const hasTare = toNumber(productSku.tare_weight, 0) > 0;
252
+ const rows = [];
253
+ if (hasTare) {
254
+ rows.push({
255
+ item: `${manualFlag}${label(locale, "gross")}: ${productSku.weight ?? 0}${unit}`,
256
+ value: ""
257
+ });
258
+ rows.push({
259
+ item: `${label(locale, "tare")}: ${productSku.tare_weight}${unit}`,
260
+ value: ""
261
+ });
262
+ }
263
+ const netWeight = productSku.net_weight ?? 0;
264
+ const unitPrice = productSku.unit_price ?? 0;
265
+ const netItem = `${netWeight} ${unit} NET @ ${currencySymbol}${unitPrice}/${unit}`;
266
+ rows.push({
267
+ item: hasTare ? netItem : `${manualFlag}${netItem}`,
268
+ value: ""
269
+ });
270
+ return rows;
271
+ }
272
+ function buildProductQuantityPriceText(params) {
273
+ const { quantity, currencySymbol, price } = params;
274
+ return `${quantity} @ ${currencySymbol}${stringify(price)} EACH`;
275
+ }
276
+ function resolveDiscountTitleWithPercent(discount, locale) {
277
+ var _a, _b;
278
+ const title = resolveDiscountTitle(discount, locale);
279
+ const percentRaw = (_a = discount.discount) == null ? void 0 : _a.percent;
280
+ const cardType = ((_b = discount.discount) == null ? void 0 : _b.discount_card_type) ?? "percent";
281
+ const percent = percentRaw !== void 0 && percentRaw !== null ? Math.trunc(Number(percentRaw)) : NaN;
282
+ if (percentRaw === void 0 || percentRaw === null)
283
+ return title;
284
+ if (cardType !== "percent")
285
+ return title;
286
+ if (Number.isNaN(percent))
287
+ return title;
288
+ return `${title} (${percent}%)`;
289
+ }
220
290
  function resolveDiscountTitle(discount, locale) {
221
291
  var _a, _b, _c;
222
292
  const title = getLocalizedValue(
@@ -540,14 +610,14 @@ function buildFees(params) {
540
610
  value: formatMoney(payProcessingFee, currencySymbol)
541
611
  });
542
612
  }
613
+ const productExpectAmount = summary.product_expect_amount || summary.product_amount || order.product_expect_amount;
614
+ const productOriginalAmount = summary.product_original_amount ?? order.product_original_amount ?? productExpectAmount;
615
+ const totalSavingsAmount = new import_decimal.default(toMoneyNumber(productOriginalAmount)).minus(toMoneyNumber(productExpectAmount)).plus(toMoneyNumber(discountAmount));
543
616
  return {
544
617
  fees,
545
618
  countFee: {
546
619
  total_amount: formatMoney(summary.total_amount || order.total_amount, currencySymbol),
547
- product_expect_amount: formatMoney(
548
- summary.product_expect_amount || summary.product_amount || order.product_expect_amount,
549
- currencySymbol
550
- ),
620
+ product_expect_amount: formatMoney(productExpectAmount, currencySymbol),
551
621
  expect_amount: formatMoney(summary.expect_amount || order.expect_amount || summary.total_amount || order.total_amount, currencySymbol),
552
622
  product_quantity: toNumber(
553
623
  summary.product_quantity || products.reduce((sum, product) => sum + product.product_quantity, 0),
@@ -558,7 +628,7 @@ function buildFees(params) {
558
628
  tax_title: stringify(summary.tax_title || order.tax_title || shopInfo.tax_title),
559
629
  total_refund_amount: formatMoney(summary.total_refund_amount || order.total_refund_amount, currencySymbol),
560
630
  ...isNonZero(roundingAmount) ? { rounding_amount: formatMoney(roundingAmount, currencySymbol) } : {},
561
- ...isNonZero(discountAmount) ? { order_total_discount: formatMoney(discountAmount, currencySymbol) } : {},
631
+ ...isNonZero(totalSavingsAmount) ? { order_total_discount: formatMoney(totalSavingsAmount, currencySymbol) } : {},
562
632
  ...isNonZero(payProcessingFee) ? { pay_processing_fee: formatMoney(payProcessingFee, currencySymbol) } : {},
563
633
  ...isNonZero(taxFee) ? { tax_fee: formatMoney(taxFee, currencySymbol) } : {}
564
634
  }
@@ -70,6 +70,11 @@ function preserveManualProductDiscountProducts(previousProducts, nextProducts) {
70
70
  return previous && isBaseSalesManualProductDiscountProduct(previous) ? previous : product;
71
71
  });
72
72
  }
73
+ function isBaseSalesHistoricalDiscountEntry(discount) {
74
+ return Boolean(
75
+ (discount == null ? void 0 : discount.isEditMode) || (discount == null ? void 0 : discount.isDisabled) || (discount == null ? void 0 : discount.order_discount_id) != null
76
+ );
77
+ }
73
78
  function getBaseSalesUniqueArrayMetadataKey(key) {
74
79
  if (key === "products" || key === "bookings")
75
80
  return "unique_identification_number";
@@ -883,7 +888,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
883
888
  const historyIds = new Set(historyDiscountList.map((discount) => discount.id));
884
889
  return [
885
890
  ...historyDiscountList,
886
- ...(discountList || []).filter((discount) => !historyIds.has(discount.id))
891
+ ...(discountList || []).filter((discount) => {
892
+ if (!historyIds.has(discount.id))
893
+ return true;
894
+ return !isBaseSalesHistoricalDiscountEntry(discount);
895
+ })
887
896
  ];
888
897
  }
889
898
  shouldSkipAutoApplyFetchedDiscountsInEditMode(params) {
@@ -906,11 +915,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
906
915
  mergeCurrentDiscountSelectionState(discountList, currentDiscountList) {
907
916
  if (!currentDiscountList.length)
908
917
  return discountList;
909
- const currentDiscountMap = new Map(
910
- currentDiscountList.map((discount) => [discount.id, discount])
911
- );
918
+ const currentDiscountMap = /* @__PURE__ */ new Map();
919
+ currentDiscountList.forEach((discount) => {
920
+ currentDiscountMap.set(
921
+ `${discount.id}:${isBaseSalesHistoricalDiscountEntry(discount) ? "historical" : "runtime"}`,
922
+ discount
923
+ );
924
+ });
912
925
  return discountList.map((discount) => {
913
- const currentDiscount = currentDiscountMap.get(discount.id);
926
+ const currentDiscount = currentDiscountMap.get(
927
+ `${discount.id}:${isBaseSalesHistoricalDiscountEntry(discount) ? "historical" : "runtime"}`
928
+ );
914
929
  if (!currentDiscount)
915
930
  return discount;
916
931
  if (currentDiscount.isManualSelect) {
@@ -1145,7 +1160,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1145
1160
  throw new Error("order 模块未初始化");
1146
1161
  const list = this.store.order.getDiscountList();
1147
1162
  const updated = list.map(
1148
- (d) => d.id === params.discountId ? {
1163
+ (d) => d.id === params.discountId && !isBaseSalesHistoricalDiscountEntry(d) ? {
1149
1164
  ...d,
1150
1165
  isSelected: params.isSelected,
1151
1166
  isManualSelect: !params.isSelected
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 5 | 1 | 4 | 2 | 3 | 6;
314
+ weekNum: 0 | 2 | 1 | 6 | 3 | 4 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.247",
4
+ "version": "2.2.248",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",