@pisell/pisellos 2.2.167 → 2.2.169

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 (54) hide show
  1. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +51 -15
  2. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +11 -1
  3. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +26 -2
  4. package/dist/modules/Customer/index.d.ts +6 -0
  5. package/dist/modules/Customer/index.js +122 -77
  6. package/dist/modules/Customer/types.d.ts +2 -0
  7. package/dist/modules/Discount/types.d.ts +1 -0
  8. package/dist/modules/Order/index.d.ts +5 -10
  9. package/dist/modules/Order/index.js +53 -9
  10. package/dist/modules/Order/types.d.ts +8 -0
  11. package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  12. package/dist/modules/Order/utils/manualProductDiscount.js +212 -0
  13. package/dist/modules/Order/utils.d.ts +4 -0
  14. package/dist/modules/Order/utils.js +25 -10
  15. package/dist/modules/Rules/index.d.ts +4 -0
  16. package/dist/modules/Rules/index.js +26 -10
  17. package/dist/server/modules/order/utils/filterOrders.js +20 -6
  18. package/dist/solution/BaseSales/index.js +11 -5
  19. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +37 -6
  20. package/dist/solution/BaseSales/utils.js +11 -2
  21. package/dist/solution/BookingByStep/index.d.ts +1 -1
  22. package/dist/solution/BookingTicket/index.d.ts +9 -0
  23. package/dist/solution/BookingTicket/index.js +372 -192
  24. package/dist/solution/BookingTicket/utils/addProductDecision.js +3 -1
  25. package/dist/solution/ScanOrder/utils.js +11 -2
  26. package/dist/solution/VenueBooking/index.d.ts +1 -6
  27. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  28. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +42 -9
  29. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +11 -1
  30. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +22 -1
  31. package/lib/modules/Customer/index.d.ts +6 -0
  32. package/lib/modules/Customer/index.js +18 -3
  33. package/lib/modules/Customer/types.d.ts +2 -0
  34. package/lib/modules/Discount/types.d.ts +1 -0
  35. package/lib/modules/Order/index.d.ts +5 -10
  36. package/lib/modules/Order/index.js +52 -5
  37. package/lib/modules/Order/types.d.ts +8 -0
  38. package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  39. package/lib/modules/Order/utils/manualProductDiscount.js +207 -0
  40. package/lib/modules/Order/utils.d.ts +4 -0
  41. package/lib/modules/Order/utils.js +46 -10
  42. package/lib/modules/Rules/index.d.ts +4 -0
  43. package/lib/modules/Rules/index.js +22 -14
  44. package/lib/server/modules/order/utils/filterOrders.js +12 -4
  45. package/lib/solution/BaseSales/index.js +6 -0
  46. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +42 -4
  47. package/lib/solution/BaseSales/utils.js +10 -2
  48. package/lib/solution/BookingByStep/index.d.ts +1 -1
  49. package/lib/solution/BookingTicket/index.d.ts +9 -0
  50. package/lib/solution/BookingTicket/index.js +78 -1
  51. package/lib/solution/BookingTicket/utils/addProductDecision.js +3 -1
  52. package/lib/solution/ScanOrder/utils.js +10 -2
  53. package/lib/solution/VenueBooking/index.d.ts +1 -6
  54. package/package.json +1 -1
@@ -30,6 +30,7 @@ import { generateDuration, getAllDiscountList, mergeRelationForms, buildSubmitPa
30
30
  import { isNormalProduct } from "../Product/utils";
31
31
  import dayjs from 'dayjs';
32
32
  import { buildProductLineFingerprint, getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
33
+ import { syncManualProductDiscountProductNum } from "./utils/manualProductDiscount";
33
34
  import { DiscountModule } from "../Discount";
34
35
  import { RulesModule } from "../Rules";
35
36
  import { UnavailableReason } from "../Rules/types";
@@ -277,6 +278,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
277
278
  type: 'clientCalc',
278
279
  isAvailable: false,
279
280
  discountList: this.getDiscountList(),
281
+ scannedDiscountList: resultDiscountList,
280
282
  unavailableReason: UnavailableReason.Unknown
281
283
  });
282
284
  case 9:
@@ -287,7 +289,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
287
289
  return _context3.abrupt("return", {
288
290
  type: 'server',
289
291
  isAvailable: false,
290
- discountList: this.getDiscountList()
292
+ discountList: this.getDiscountList(),
293
+ scannedDiscountList: resultDiscountList
291
294
  });
292
295
  case 11:
293
296
  withScanList = resultDiscountList.map(function (item) {
@@ -309,7 +312,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
309
312
  return _context3.abrupt("return", {
310
313
  type: 'clientCalc',
311
314
  isAvailable: true,
312
- discountList: this.getDiscountList()
315
+ discountList: this.getDiscountList(),
316
+ scannedDiscountList: resultDiscountList
313
317
  });
314
318
  case 15:
315
319
  tempOrder = this.store.tempOrder;
@@ -335,6 +339,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
335
339
  type: 'clientCalc',
336
340
  isAvailable: isAvailable || false,
337
341
  discountList: newDiscountList || this.getDiscountList(),
342
+ scannedDiscountList: resultDiscountList,
338
343
  unavailableReason: unavailableReason
339
344
  });
340
345
  case 20:
@@ -371,7 +376,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
371
376
  orderTotalAmount: Number(((_this$store$summary2 = this.store.summary) === null || _this$store$summary2 === void 0 ? void 0 : _this$store$summary2.total_amount) || 0)
372
377
  });
373
378
  if (result !== null && result !== void 0 && result.productList) {
374
- tempOrder.products = result.productList;
379
+ tempOrder.products = (result.productList || []).map(function (product) {
380
+ return _objectSpread(_objectSpread({}, product), {}, {
381
+ discount_list: syncManualProductDiscountProductNum(product.discount_list, product.num)
382
+ });
383
+ });
375
384
  }
376
385
  if (result !== null && result !== void 0 && result.discountList) {
377
386
  var _this$store$discount8;
@@ -1280,25 +1289,51 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1280
1289
  this.persistTempOrder();
1281
1290
  return tempOrder.contacts_info;
1282
1291
  }
1292
+ }, {
1293
+ key: "buildTempOrderCustomer",
1294
+ value: function buildTempOrderCustomer(params) {
1295
+ var _ref8, _ref9, _ref10, _source$name, _ref11, _ref12, _ref13, _source$customer_name, _source$id, _source$customer_id, _ref14, _source$country_calli, _source$phone, _source$email;
1296
+ if (!params.customerId) return null;
1297
+ var source = params.source ? cloneDeep(params.source) : {};
1298
+ var name = (_ref8 = (_ref9 = (_ref10 = (_source$name = source.name) !== null && _source$name !== void 0 ? _source$name : source.display_name) !== null && _ref10 !== void 0 ? _ref10 : source.customerName) !== null && _ref9 !== void 0 ? _ref9 : source.customer_name) !== null && _ref8 !== void 0 ? _ref8 : params.customerName;
1299
+ var customerName = (_ref11 = (_ref12 = (_ref13 = (_source$customer_name = source.customer_name) !== null && _source$customer_name !== void 0 ? _source$customer_name : source.customerName) !== null && _ref13 !== void 0 ? _ref13 : source.display_name) !== null && _ref12 !== void 0 ? _ref12 : source.name) !== null && _ref11 !== void 0 ? _ref11 : params.customerName;
1300
+ return _objectSpread(_objectSpread({}, source), {}, {
1301
+ id: (_source$id = source.id) !== null && _source$id !== void 0 ? _source$id : params.customerId,
1302
+ customer_id: (_source$customer_id = source.customer_id) !== null && _source$customer_id !== void 0 ? _source$customer_id : params.customerId,
1303
+ name: String(name || ''),
1304
+ customer_name: String(customerName || ''),
1305
+ country_calling_code: String((_ref14 = (_source$country_calli = source.country_calling_code) !== null && _source$country_calli !== void 0 ? _source$country_calli : source.countryCallingCode) !== null && _ref14 !== void 0 ? _ref14 : params.countryCallingCode),
1306
+ phone: String((_source$phone = source.phone) !== null && _source$phone !== void 0 ? _source$phone : params.phone),
1307
+ email: String((_source$email = source.email) !== null && _source$email !== void 0 ? _source$email : params.email)
1308
+ });
1309
+ }
1283
1310
 
1284
1311
  /**
1285
1312
  * 更新当前 tempOrder 的客户协议字段。
1286
1313
  *
1287
- * PaymentModal 只需要修改订单里的客户字段;如果外部还有客户模块需要同步,
1314
+ * PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
1288
1315
  * 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
1289
1316
  */
1290
1317
  }, {
1291
1318
  key: "updateTempOrderCustomer",
1292
1319
  value: function updateTempOrderCustomer(customer) {
1293
- var _ref8, _ref9, _customer$customer_id, _ref10, _ref11, _ref12, _customer$customer_na, _ref13, _customer$country_cal;
1320
+ var _ref15, _ref16, _customer$customer_id, _ref17, _ref18, _ref19, _customer$customer_na, _ref20, _customer$country_cal;
1294
1321
  var tempOrder = this.ensureTempOrder();
1295
- var customerId = (_ref8 = (_ref9 = (_customer$customer_id = customer.customer_id) !== null && _customer$customer_id !== void 0 ? _customer$customer_id : customer.customerId) !== null && _ref9 !== void 0 ? _ref9 : customer.id) !== null && _ref8 !== void 0 ? _ref8 : null;
1296
- var customerName = (_ref10 = (_ref11 = (_ref12 = (_customer$customer_na = customer.customer_name) !== null && _customer$customer_na !== void 0 ? _customer$customer_na : customer.customerName) !== null && _ref12 !== void 0 ? _ref12 : customer.display_name) !== null && _ref11 !== void 0 ? _ref11 : customer.name) !== null && _ref10 !== void 0 ? _ref10 : '';
1322
+ var customerId = (_ref15 = (_ref16 = (_customer$customer_id = customer.customer_id) !== null && _customer$customer_id !== void 0 ? _customer$customer_id : customer.customerId) !== null && _ref16 !== void 0 ? _ref16 : customer.id) !== null && _ref15 !== void 0 ? _ref15 : null;
1323
+ var customerName = (_ref17 = (_ref18 = (_ref19 = (_customer$customer_na = customer.customer_name) !== null && _customer$customer_na !== void 0 ? _customer$customer_na : customer.customerName) !== null && _ref19 !== void 0 ? _ref19 : customer.display_name) !== null && _ref18 !== void 0 ? _ref18 : customer.name) !== null && _ref17 !== void 0 ? _ref17 : '';
1297
1324
  tempOrder.customer_id = customerId === null || customerId === undefined || customerId === '' ? null : Number(customerId);
1298
1325
  tempOrder.customer_name = String(customerName || '');
1299
- tempOrder.country_calling_code = String((_ref13 = (_customer$country_cal = customer.country_calling_code) !== null && _customer$country_cal !== void 0 ? _customer$country_cal : customer.countryCallingCode) !== null && _ref13 !== void 0 ? _ref13 : '');
1326
+ tempOrder.country_calling_code = String((_ref20 = (_customer$country_cal = customer.country_calling_code) !== null && _customer$country_cal !== void 0 ? _customer$country_cal : customer.countryCallingCode) !== null && _ref20 !== void 0 ? _ref20 : '');
1300
1327
  tempOrder.phone = String(customer.phone || '');
1301
1328
  tempOrder.email = String(customer.email || '');
1329
+ tempOrder.customer = this.buildTempOrderCustomer({
1330
+ source: customer,
1331
+ customerId: tempOrder.customer_id,
1332
+ customerName: tempOrder.customer_name,
1333
+ countryCallingCode: tempOrder.country_calling_code,
1334
+ phone: tempOrder.phone,
1335
+ email: tempOrder.email
1336
+ });
1302
1337
  this.persistTempOrder();
1303
1338
  return {
1304
1339
  customerId: tempOrder.customer_id,
@@ -1320,6 +1355,14 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1320
1355
  tempOrder.country_calling_code = String(patch.country_calling_code || '');
1321
1356
  tempOrder.phone = String(patch.phone || '');
1322
1357
  tempOrder.email = String(patch.email || '');
1358
+ tempOrder.customer = this.buildTempOrderCustomer({
1359
+ source: snapshot || null,
1360
+ customerId: tempOrder.customer_id,
1361
+ customerName: tempOrder.customer_name,
1362
+ countryCallingCode: tempOrder.country_calling_code,
1363
+ phone: tempOrder.phone,
1364
+ email: tempOrder.email
1365
+ });
1323
1366
  if (snapshot !== undefined) {
1324
1367
  var extend = this.ensureExtend(tempOrder);
1325
1368
  if (snapshot === null) delete extend.customerSnapshot;else extend.customerSnapshot = cloneDeep(snapshot);
@@ -1354,11 +1397,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1354
1397
  key: "clearOrderCustomer",
1355
1398
  value: function clearOrderCustomer() {
1356
1399
  var tempOrder = this.ensureTempOrder();
1357
- tempOrder.customer_id = 0;
1400
+ tempOrder.customer_id = null;
1358
1401
  tempOrder.customer_name = '';
1359
1402
  tempOrder.country_calling_code = '';
1360
1403
  tempOrder.phone = '';
1361
1404
  tempOrder.email = '';
1405
+ tempOrder.customer = null;
1362
1406
  if (tempOrder._extend) delete tempOrder._extend.customerSnapshot;
1363
1407
  this.persistTempOrder();
1364
1408
  this.saveDraftInBackground();
@@ -2,6 +2,7 @@ import { CartItem } from '../Cart/types';
2
2
  import type { DiscountModule } from '../Discount';
3
3
  import type { RulesModule } from '../Rules';
4
4
  import type { Discount } from '../Discount/types';
5
+ import type { UnavailableReason } from '../Rules/types';
5
6
  import type { SubmitPayloadEnhancer } from './utils';
6
7
  import type { PaymentItem } from '../Payment/types';
7
8
  import type { ICustomer } from '../AccountList/types';
@@ -48,6 +49,13 @@ export interface OrderCustomerChangePayload {
48
49
  patch: OrderCustomerView;
49
50
  snapshot: ICustomer | null;
50
51
  }
52
+ export interface OrderScanCodeResult {
53
+ isAvailable: boolean;
54
+ discountList: Discount[];
55
+ scannedDiscountList: Discount[];
56
+ type: 'server' | 'clientCalc';
57
+ unavailableReason?: UnavailableReason;
58
+ }
51
59
  export interface OrderProductIdentity {
52
60
  product_id: number | null;
53
61
  product_variant_id: number;
@@ -0,0 +1,106 @@
1
+ /** 解析商品行数量(checkout 协议 product_num 语义 = 当前行 num) */
2
+ export declare function resolveSafeProductNum(num?: number | null): number;
3
+ /**
4
+ * 将 discount_list 中 type=product 项的 product_num 同步为当前商品数量。
5
+ *
6
+ * @example
7
+ * syncManualProductDiscountProductNum(line.discount_list, line.num);
8
+ */
9
+ export declare function syncManualProductDiscountProductNum(discountList: any[] | undefined | null, productNum?: number | null): any[];
10
+ /** 从多源解析改价前行总价(与 cacheItem._extend.origin_total 语义一致) */
11
+ export declare function resolveManualDiscountOriginTotal(sources: {
12
+ originTotal?: unknown;
13
+ extendOriginTotal?: unknown;
14
+ originExtendOriginTotal?: unknown;
15
+ sourceExtendOriginTotal?: unknown;
16
+ catalogUnitPrice?: unknown;
17
+ quantity?: number;
18
+ }): number;
19
+ /** 从 payload / extend / origin 解析手动折扣原因 */
20
+ export declare function resolveManualDiscountReasonFromSources(sources: {
21
+ discountReason?: unknown;
22
+ extendDiscountReason?: unknown;
23
+ originExtendDiscountReason?: unknown;
24
+ }): string;
25
+ /** 是否带手动改价标记(price_override / is_manual_discount) */
26
+ export declare function hasManualProductDiscountFlag(metadata?: Record<string, any> | null): boolean;
27
+ /**
28
+ * normalize 兜底:手动改价但 discount_list 缺 type=product 时,按行级原价/折后价补写。
29
+ *
30
+ * @example
31
+ * ensureManualProductDiscountList({
32
+ * discountList: [],
33
+ * metadata: { price_override: '5', is_manual_discount: 1 },
34
+ * originalPrice: '11.00',
35
+ * sellingPrice: '5.00',
36
+ * quantity: 1,
37
+ * });
38
+ */
39
+ export declare function ensureManualProductDiscountList(params: {
40
+ discountList?: any[] | null;
41
+ metadata?: Record<string, any> | null;
42
+ originalPrice: string | number;
43
+ sellingPrice: string | number;
44
+ quantity?: number;
45
+ }): any[];
46
+ /** 商品手动折扣 discount_list 项(checkout 协议,type = product) */
47
+ export interface ManualProductDiscountItem {
48
+ amount: number;
49
+ type: 'product';
50
+ discount: {
51
+ message: string;
52
+ discountway: string;
53
+ product_num: number;
54
+ discount_per: string;
55
+ discount_type: 'discount' | 'change_price';
56
+ };
57
+ }
58
+ /**
59
+ * 从 discount_list 中取手动改价项(type = product)。
60
+ *
61
+ * @example
62
+ * const manual = findManualProductDiscountItem(product.discount_list);
63
+ * manual?.discount.message; // 折扣原因
64
+ */
65
+ export declare function findManualProductDiscountItem(discountList?: any[] | null): ManualProductDiscountItem | undefined;
66
+ /**
67
+ * 解析折扣原因:优先 discount_list[type=product].discount.message。
68
+ *
69
+ * @example
70
+ * resolveManualDiscountMessage(line.discount_list, line.metadata?.legacy_reason);
71
+ */
72
+ export declare function resolveManualDiscountMessage(discountList?: any[] | null, fallback?: string): string;
73
+ /** 去掉 discount_list 中已有的手动改价项,避免重复叠加 */
74
+ export declare function stripManualProductDiscountItems(discountList?: any[] | null): any[];
75
+ /**
76
+ * 由改价前后行总价构建手动折扣项;amount = |originTotal - sellingTotal|(行级差额)。
77
+ *
78
+ * @example
79
+ * buildManualProductDiscountItem({
80
+ * originTotal: 11,
81
+ * sellingTotal: 4,
82
+ * quantity: 1,
83
+ * message: 'VIP',
84
+ * });
85
+ */
86
+ export declare function buildManualProductDiscountItem(params: {
87
+ originTotal: number;
88
+ sellingTotal: number;
89
+ quantity?: number;
90
+ message?: string;
91
+ discountway?: string;
92
+ discount_per?: string;
93
+ }): ManualProductDiscountItem;
94
+ /**
95
+ * 将手动改价项合并进 discount_list(替换已有 type=product 项)。
96
+ *
97
+ * @example
98
+ * mergeManualProductDiscountIntoList(coupons, manualItem);
99
+ */
100
+ export declare function mergeManualProductDiscountIntoList(discountList: any[] | undefined | null, manualItem: ManualProductDiscountItem | null | undefined): any[];
101
+ /** 是否应写入手动改价 discount_list 项 */
102
+ export declare function shouldBuildManualProductDiscount(params: {
103
+ hasPriceOverride?: boolean;
104
+ originTotal?: number;
105
+ sellingTotal?: number;
106
+ }): boolean;
@@ -0,0 +1,212 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ 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."); }
4
+ 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); }
5
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
6
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
7
+ 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; }
8
+ 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; }
9
+ 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; }
10
+ 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; }
11
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
12
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
13
+ import Decimal from 'decimal.js';
14
+
15
+ /** 解析商品行数量(checkout 协议 product_num 语义 = 当前行 num) */
16
+ export function resolveSafeProductNum(num) {
17
+ var parsed = Number(num);
18
+ if (!Number.isFinite(parsed) || parsed <= 0) return 1;
19
+ return Math.floor(parsed);
20
+ }
21
+
22
+ /**
23
+ * 将 discount_list 中 type=product 项的 product_num 同步为当前商品数量。
24
+ *
25
+ * @example
26
+ * syncManualProductDiscountProductNum(line.discount_list, line.num);
27
+ */
28
+ export function syncManualProductDiscountProductNum(discountList, productNum) {
29
+ var quantity = resolveSafeProductNum(productNum);
30
+ return (discountList || []).map(function (item) {
31
+ if ((item === null || item === void 0 ? void 0 : item.type) !== 'product') return item;
32
+ return _objectSpread(_objectSpread({}, item), {}, {
33
+ discount: _objectSpread(_objectSpread({}, item.discount || {}), {}, {
34
+ product_num: quantity
35
+ })
36
+ });
37
+ });
38
+ }
39
+
40
+ /** 从多源解析改价前行总价(与 cacheItem._extend.origin_total 语义一致) */
41
+ export function resolveManualDiscountOriginTotal(sources) {
42
+ var _sources$quantity;
43
+ var candidates = [sources.originTotal, sources.extendOriginTotal, sources.originExtendOriginTotal, sources.sourceExtendOriginTotal];
44
+ for (var _i = 0, _candidates = candidates; _i < _candidates.length; _i++) {
45
+ var candidate = _candidates[_i];
46
+ if (candidate === undefined || candidate === null || candidate === '') continue;
47
+ var parsed = Number(candidate);
48
+ if (Number.isFinite(parsed)) return parsed;
49
+ }
50
+ var unit = Number(sources.catalogUnitPrice);
51
+ var quantity = (_sources$quantity = sources.quantity) !== null && _sources$quantity !== void 0 ? _sources$quantity : 1;
52
+ if (Number.isFinite(unit) && unit > 0) {
53
+ return new Decimal(unit).mul(quantity).toNumber();
54
+ }
55
+ return NaN;
56
+ }
57
+
58
+ /** 从 payload / extend / origin 解析手动折扣原因 */
59
+ export function resolveManualDiscountReasonFromSources(sources) {
60
+ for (var _i2 = 0, _arr = [sources.discountReason, sources.extendDiscountReason, sources.originExtendDiscountReason]; _i2 < _arr.length; _i2++) {
61
+ var candidate = _arr[_i2];
62
+ if (candidate != null && String(candidate).trim() !== '') {
63
+ return String(candidate);
64
+ }
65
+ }
66
+ return '';
67
+ }
68
+
69
+ /** 是否带手动改价标记(price_override / is_manual_discount) */
70
+ export function hasManualProductDiscountFlag(metadata) {
71
+ if (!metadata) return false;
72
+ var override = metadata.price_override;
73
+ if (override !== undefined && override !== null && override !== '') {
74
+ return true;
75
+ }
76
+ return metadata.is_manual_discount === 1 || metadata.is_manual_discount === true;
77
+ }
78
+
79
+ /**
80
+ * normalize 兜底:手动改价但 discount_list 缺 type=product 时,按行级原价/折后价补写。
81
+ *
82
+ * @example
83
+ * ensureManualProductDiscountList({
84
+ * discountList: [],
85
+ * metadata: { price_override: '5', is_manual_discount: 1 },
86
+ * originalPrice: '11.00',
87
+ * sellingPrice: '5.00',
88
+ * quantity: 1,
89
+ * });
90
+ */
91
+ export function ensureManualProductDiscountList(params) {
92
+ var _metadata$origin, _metadata$origin2, _metadata$origin3, _metadata$origin4;
93
+ var list = params.discountList || [];
94
+ var quantity = resolveSafeProductNum(params.quantity);
95
+ if (findManualProductDiscountItem(list)) {
96
+ return syncManualProductDiscountProductNum(list, quantity);
97
+ }
98
+ var metadata = params.metadata || {};
99
+ var originalNum = Number(params.originalPrice);
100
+ var sellingNum = Number(params.sellingPrice);
101
+ var shouldBuild = hasManualProductDiscountFlag(metadata) || shouldBuildManualProductDiscount({
102
+ originTotal: originalNum,
103
+ sellingTotal: sellingNum
104
+ });
105
+ if (!shouldBuild) {
106
+ return list;
107
+ }
108
+ if (!Number.isFinite(originalNum) || !Number.isFinite(sellingNum) || originalNum === sellingNum) {
109
+ return list;
110
+ }
111
+ var message = resolveManualDiscountMessage(list, resolveManualDiscountReasonFromSources({
112
+ extendDiscountReason: (_metadata$origin = metadata.origin) === null || _metadata$origin === void 0 || (_metadata$origin = _metadata$origin._extend) === null || _metadata$origin === void 0 ? void 0 : _metadata$origin.discount_reason,
113
+ originExtendDiscountReason: (_metadata$origin2 = metadata.origin) === null || _metadata$origin2 === void 0 || (_metadata$origin2 = _metadata$origin2._extend) === null || _metadata$origin2 === void 0 ? void 0 : _metadata$origin2.discount_reason
114
+ }));
115
+ return mergeManualProductDiscountIntoList(list, buildManualProductDiscountItem({
116
+ originTotal: originalNum,
117
+ sellingTotal: sellingNum,
118
+ quantity: quantity,
119
+ message: message,
120
+ discountway: (_metadata$origin3 = metadata.origin) === null || _metadata$origin3 === void 0 || (_metadata$origin3 = _metadata$origin3._extend) === null || _metadata$origin3 === void 0 ? void 0 : _metadata$origin3.discountway,
121
+ discount_per: (_metadata$origin4 = metadata.origin) === null || _metadata$origin4 === void 0 || (_metadata$origin4 = _metadata$origin4._extend) === null || _metadata$origin4 === void 0 ? void 0 : _metadata$origin4.discount_per
122
+ }));
123
+ }
124
+
125
+ /** 商品手动折扣 discount_list 项(checkout 协议,type = product) */
126
+
127
+ /**
128
+ * 从 discount_list 中取手动改价项(type = product)。
129
+ *
130
+ * @example
131
+ * const manual = findManualProductDiscountItem(product.discount_list);
132
+ * manual?.discount.message; // 折扣原因
133
+ */
134
+ export function findManualProductDiscountItem(discountList) {
135
+ return (discountList || []).find(function (item) {
136
+ return (item === null || item === void 0 ? void 0 : item.type) === 'product';
137
+ });
138
+ }
139
+
140
+ /**
141
+ * 解析折扣原因:优先 discount_list[type=product].discount.message。
142
+ *
143
+ * @example
144
+ * resolveManualDiscountMessage(line.discount_list, line.metadata?.legacy_reason);
145
+ */
146
+ export function resolveManualDiscountMessage(discountList, fallback) {
147
+ var _findManualProductDis;
148
+ var message = (_findManualProductDis = findManualProductDiscountItem(discountList)) === null || _findManualProductDis === void 0 || (_findManualProductDis = _findManualProductDis.discount) === null || _findManualProductDis === void 0 ? void 0 : _findManualProductDis.message;
149
+ if (message != null && String(message).trim() !== '') {
150
+ return String(message);
151
+ }
152
+ return fallback !== null && fallback !== void 0 ? fallback : '';
153
+ }
154
+
155
+ /** 去掉 discount_list 中已有的手动改价项,避免重复叠加 */
156
+ export function stripManualProductDiscountItems(discountList) {
157
+ return (discountList || []).filter(function (item) {
158
+ return (item === null || item === void 0 ? void 0 : item.type) !== 'product';
159
+ });
160
+ }
161
+
162
+ /**
163
+ * 由改价前后行总价构建手动折扣项;amount = |originTotal - sellingTotal|(行级差额)。
164
+ *
165
+ * @example
166
+ * buildManualProductDiscountItem({
167
+ * originTotal: 11,
168
+ * sellingTotal: 4,
169
+ * quantity: 1,
170
+ * message: 'VIP',
171
+ * });
172
+ */
173
+ export function buildManualProductDiscountItem(params) {
174
+ var _params$message, _params$discountway, _params$discount_per;
175
+ var origin = new Decimal(Number(params.originTotal) || 0);
176
+ var selling = new Decimal(Number(params.sellingTotal) || 0);
177
+ var diff = origin.minus(selling);
178
+ var quantity = resolveSafeProductNum(params.quantity);
179
+ return {
180
+ amount: diff.abs().toDecimalPlaces(2).toNumber(),
181
+ type: 'product',
182
+ discount: {
183
+ message: (_params$message = params.message) !== null && _params$message !== void 0 ? _params$message : '',
184
+ discountway: (_params$discountway = params.discountway) !== null && _params$discountway !== void 0 ? _params$discountway : 'num',
185
+ product_num: quantity,
186
+ discount_per: (_params$discount_per = params.discount_per) !== null && _params$discount_per !== void 0 ? _params$discount_per : '',
187
+ discount_type: diff.isNegative() ? 'change_price' : 'discount'
188
+ }
189
+ };
190
+ }
191
+
192
+ /**
193
+ * 将手动改价项合并进 discount_list(替换已有 type=product 项)。
194
+ *
195
+ * @example
196
+ * mergeManualProductDiscountIntoList(coupons, manualItem);
197
+ */
198
+ export function mergeManualProductDiscountIntoList(discountList, manualItem) {
199
+ var base = stripManualProductDiscountItems(discountList);
200
+ if (!manualItem) return base;
201
+ if (manualItem.amount === 0 && !manualItem.discount.message) return base;
202
+ return [].concat(_toConsumableArray(base), [manualItem]);
203
+ }
204
+
205
+ /** 是否应写入手动改价 discount_list 项 */
206
+ export function shouldBuildManualProductDiscount(params) {
207
+ if (params.hasPriceOverride) return true;
208
+ var origin = Number(params.originTotal);
209
+ var selling = Number(params.sellingTotal);
210
+ if (!Number.isFinite(origin) || !Number.isFinite(selling)) return false;
211
+ return origin !== selling;
212
+ }
@@ -77,6 +77,8 @@ export declare function resolveRulesManualDiscountFlag(metadata: Record<string,
77
77
  export declare function resolveManualOverrideLineOriginalPrice(params: {
78
78
  num?: number;
79
79
  metadata?: Record<string, any> | null;
80
+ /** 已有行级 original_price(origin 被裁剪时兜底划线价) */
81
+ lineOriginalPrice?: string | number | null;
80
82
  }, fallbackCompositeOriginal: string): string;
81
83
  export declare function createDefaultOrderRulesHooks(): RulesParamsHooks;
82
84
  /**
@@ -154,3 +156,5 @@ export declare function formatV1Product(products: OrderSubmitProduct[]): {
154
156
  unique: string;
155
157
  }[];
156
158
  export { createEmptySummary } from '../../solution/ScanOrder/utils';
159
+ export { buildManualProductDiscountItem, ensureManualProductDiscountList, findManualProductDiscountItem, mergeManualProductDiscountIntoList, resolveManualDiscountMessage, resolveManualDiscountOriginTotal, resolveManualDiscountReasonFromSources, resolveSafeProductNum, shouldBuildManualProductDiscount, syncManualProductDiscountProductNum, stripManualProductDiscountItems, } from './utils/manualProductDiscount';
160
+ export type { ManualProductDiscountItem } from './utils/manualProductDiscount';
@@ -1,5 +1,5 @@
1
1
  var _excluded = ["unique_identification_number"],
2
- _excluded2 = ["num", "product_option_item", "surcharge_fee"],
2
+ _excluded2 = ["num", "product_option_item", "surcharge_fee", "discount_amount", "discount_type", "discountway", "product_discount_reason", "discount_per"],
3
3
  _excluded3 = ["_extend", "relation_id", "table_form_id", "resource_id", "summary", "lastOrderInfo", "paid_amount", "shop_id", "shop_note", "shop_service_type", "start_time", "customer", "tax_fee", "total_amount", "total_refund_amount", "create_date", "holder_id"],
4
4
  _excluded4 = ["collect_pax", "table_occupancy_duration"];
5
5
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
@@ -142,14 +142,21 @@ export function resolveManualOverrideLineOriginalPrice(params, fallbackComposite
142
142
  return fallbackCompositeOriginal;
143
143
  }
144
144
  var refTotal = (_metadata$origin = metadata.origin) === null || _metadata$origin === void 0 || (_metadata$origin = _metadata$origin._extend) === null || _metadata$origin === void 0 ? void 0 : _metadata$origin.origin_total;
145
- if (refTotal === undefined || refTotal === null || refTotal === '') {
146
- return fallbackCompositeOriginal;
145
+ if (refTotal !== undefined && refTotal !== null && refTotal !== '') {
146
+ var parsed = Number(refTotal);
147
+ if (Number.isFinite(parsed)) {
148
+ return new Decimal(parsed).toDecimalPlaces(2).toFixed(2);
149
+ }
147
150
  }
148
- var parsed = Number(refTotal);
149
- if (!Number.isFinite(parsed)) {
150
- return fallbackCompositeOriginal;
151
+ var lineOriginal = params.lineOriginalPrice;
152
+ if (lineOriginal !== undefined && lineOriginal !== null && lineOriginal !== '') {
153
+ var parsedLine = Number(lineOriginal);
154
+ var parsedFallback = Number(fallbackCompositeOriginal);
155
+ if (Number.isFinite(parsedLine) && Number.isFinite(parsedFallback) && parsedLine > parsedFallback) {
156
+ return new Decimal(parsedLine).toDecimalPlaces(2).toFixed(2);
157
+ }
151
158
  }
152
- return new Decimal(parsed).toDecimalPlaces(2).toFixed(2);
159
+ return fallbackCompositeOriginal;
153
160
  }
154
161
  export function createDefaultOrderRulesHooks() {
155
162
  var toUnitPriceString = function toUnitPriceString(totalLike, num) {
@@ -238,7 +245,8 @@ export function createDefaultOrderRulesHooks() {
238
245
  });
239
246
  var finalOriginalPrice = resolveManualOverrideLineOriginalPrice({
240
247
  num: nextNum,
241
- metadata: metadataAny
248
+ metadata: metadataAny,
249
+ lineOriginalPrice: product.original_price
242
250
  }, composedOriginalPrice);
243
251
  return _objectSpread(_objectSpread({}, product), {}, {
244
252
  selling_price: composedSellingPrice,
@@ -438,6 +446,11 @@ function normalizeSubmitProduct(product) {
438
446
  var num = submitProduct.num,
439
447
  productOptionItem = submitProduct.product_option_item,
440
448
  _productSurchargeFee = submitProduct.surcharge_fee,
449
+ _deprecatedDiscountAmount = submitProduct.discount_amount,
450
+ _deprecatedDiscountType = submitProduct.discount_type,
451
+ _deprecatedDiscountway = submitProduct.discountway,
452
+ _deprecatedProductDiscountReason = submitProduct.product_discount_reason,
453
+ _deprecatedDiscountPer = submitProduct.discount_per,
441
454
  productRest = _objectWithoutProperties(submitProduct, _excluded2);
442
455
  var rawMetadata = submitProduct.metadata || {};
443
456
  var bookingUid = rawMetadata.booking_uid;
@@ -562,6 +575,7 @@ export function createDefaultTempOrder(params) {
562
575
  country_calling_code: '',
563
576
  phone: '',
564
577
  email: '',
578
+ customer: null,
565
579
  is_price_include_tax: 1,
566
580
  tax_title: '',
567
581
  tax_country_code: '',
@@ -655,7 +669,7 @@ export function buildSubmitPayload(params) {
655
669
  note: tempOrder.note || '',
656
670
  delivery_type: tempOrder.delivery_type || 'nil',
657
671
  schedule_date: scheduleDate,
658
- created_at: tempOrder.created_at || formatDateTime(now),
672
+ // created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
659
673
  bookings: (tempOrder.bookings || []).filter(function (booking) {
660
674
  return Number(booking.parent_id) !== 0;
661
675
  }).map(function (booking) {
@@ -767,4 +781,5 @@ export function formatV1Product(products) {
767
781
  };
768
782
  });
769
783
  }
770
- export { createEmptySummary } from "../../solution/ScanOrder/utils";
784
+ export { createEmptySummary } from "../../solution/ScanOrder/utils";
785
+ export { buildManualProductDiscountItem, ensureManualProductDiscountList, findManualProductDiscountItem, mergeManualProductDiscountIntoList, resolveManualDiscountMessage, resolveManualDiscountOriginTotal, resolveManualDiscountReasonFromSources, resolveSafeProductNum, shouldBuildManualProductDiscount, syncManualProductDiscountProductNum, stripManualProductDiscountItems } from "./utils/manualProductDiscount";
@@ -32,6 +32,10 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
32
32
  unavailableReason?: UnavailableReason;
33
33
  };
34
34
  filterDiscountListByType(discountList: Discount[], type: string): Discount[];
35
+ /** 剔除指定 type/tag 的折扣项,保留手动改价(type=product) / 券等 */
36
+ excludeDiscountListByType(discountList: Discount[], type: string): Discount[];
37
+ /** 手动改价场景:去掉 promotion,保留 type=product 等行内折扣 */
38
+ resolveDiscountListForManualOverride(discountList: Discount[]): Discount[];
35
39
  private getUnavailableReason;
36
40
  calcDiscount({ discountList, productList, holders, isFormSubject, orderTotalAmount }: {
37
41
  discountList: Discount[];