@pisell/pisellos 2.2.266 → 2.2.268

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 (98) hide show
  1. package/dist/model/strategy/adapter/promotion/adapter.d.ts +0 -4
  2. package/dist/model/strategy/adapter/promotion/adapter.js +0 -23
  3. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
  4. package/dist/model/strategy/adapter/promotion/evaluator.js +6 -279
  5. package/dist/model/strategy/adapter/promotion/examples.d.ts +0 -86
  6. package/dist/model/strategy/adapter/promotion/examples.js +0 -99
  7. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  8. package/dist/model/strategy/adapter/promotion/type.d.ts +2 -90
  9. package/dist/model/strategy/adapter/promotion/type.js +0 -45
  10. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -3
  11. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +6 -3
  12. package/dist/modules/Order/index.d.ts +13 -32
  13. package/dist/modules/Order/index.js +562 -778
  14. package/dist/modules/Order/types.d.ts +22 -36
  15. package/dist/modules/Order/types.js +11 -0
  16. package/dist/modules/Order/utils/orderCollectionIdentity.js +2 -7
  17. package/dist/modules/Order/utils.js +6 -10
  18. package/dist/modules/Payment/index.d.ts +0 -2
  19. package/dist/modules/Payment/index.js +50 -79
  20. package/dist/modules/Payment/types.d.ts +27 -29
  21. package/dist/modules/Payment/types.js +3 -5
  22. package/dist/modules/Rules/index.d.ts +0 -1
  23. package/dist/modules/Rules/index.js +14 -34
  24. package/dist/server/index.d.ts +0 -16
  25. package/dist/server/index.js +1036 -1933
  26. package/dist/server/modules/order/index.d.ts +4 -49
  27. package/dist/server/modules/order/index.js +695 -1574
  28. package/dist/server/modules/order/types.d.ts +3 -11
  29. package/dist/server/modules/order/types.js +1 -1
  30. package/dist/solution/BaseSales/index.d.ts +14 -58
  31. package/dist/solution/BaseSales/index.js +398 -713
  32. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
  33. package/dist/solution/BaseSales/utils/cartPromotion.js +36 -93
  34. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +1 -6
  35. package/dist/solution/BookingByStep/index.d.ts +1 -1
  36. package/dist/solution/BookingTicket/index.js +29 -35
  37. package/dist/solution/BookingTicket/types.d.ts +3 -0
  38. package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -0
  39. package/dist/solution/BookingTicket/utils/cartView.js +44 -32
  40. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  41. package/dist/solution/BookingTicket/utils/weighingProductSku.js +45 -0
  42. package/dist/solution/Sales/index.d.ts +0 -1
  43. package/dist/solution/Sales/index.js +2 -10
  44. package/dist/solution/ScanOrder/index.js +20 -31
  45. package/dist/solution/VenueBooking/index.js +19 -30
  46. package/lib/model/strategy/adapter/promotion/adapter.d.ts +0 -4
  47. package/lib/model/strategy/adapter/promotion/adapter.js +0 -20
  48. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
  49. package/lib/model/strategy/adapter/promotion/evaluator.js +0 -235
  50. package/lib/model/strategy/adapter/promotion/examples.d.ts +0 -86
  51. package/lib/model/strategy/adapter/promotion/examples.js +0 -91
  52. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  53. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  54. package/lib/model/strategy/adapter/promotion/type.d.ts +2 -90
  55. package/lib/model/strategy/adapter/promotion/type.js +0 -2
  56. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  57. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  58. package/lib/modules/Order/index.d.ts +13 -32
  59. package/lib/modules/Order/index.js +142 -201
  60. package/lib/modules/Order/types.d.ts +22 -36
  61. package/lib/modules/Order/utils/orderCollectionIdentity.js +0 -3
  62. package/lib/modules/Order/utils.js +4 -11
  63. package/lib/modules/Payment/index.d.ts +0 -2
  64. package/lib/modules/Payment/index.js +13 -34
  65. package/lib/modules/Payment/types.d.ts +27 -29
  66. package/lib/modules/Payment/types.js +3 -3
  67. package/lib/modules/Rules/index.d.ts +0 -1
  68. package/lib/modules/Rules/index.js +4 -23
  69. package/lib/server/index.d.ts +0 -16
  70. package/lib/server/index.js +18 -670
  71. package/lib/server/modules/order/index.d.ts +4 -49
  72. package/lib/server/modules/order/index.js +66 -657
  73. package/lib/server/modules/order/types.d.ts +3 -11
  74. package/lib/solution/BaseSales/index.d.ts +14 -58
  75. package/lib/solution/BaseSales/index.js +41 -241
  76. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
  77. package/lib/solution/BaseSales/utils/cartPromotion.js +17 -65
  78. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +1 -6
  79. package/lib/solution/BookingByStep/index.d.ts +1 -1
  80. package/lib/solution/BookingTicket/index.js +3 -6
  81. package/lib/solution/BookingTicket/types.d.ts +3 -0
  82. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -0
  83. package/lib/solution/BookingTicket/utils/cartView.js +43 -30
  84. package/lib/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  85. package/lib/solution/BookingTicket/utils/weighingProductSku.js +63 -0
  86. package/lib/solution/Sales/index.d.ts +0 -1
  87. package/lib/solution/Sales/index.js +3 -5
  88. package/lib/solution/ScanOrder/index.js +0 -8
  89. package/lib/solution/VenueBooking/index.js +0 -8
  90. package/package.json +2 -2
  91. package/dist/modules/Order/payment-utils.d.ts +0 -26
  92. package/dist/modules/Order/payment-utils.js +0 -225
  93. package/dist/utils/payment-number.d.ts +0 -9
  94. package/dist/utils/payment-number.js +0 -69
  95. package/lib/modules/Order/payment-utils.d.ts +0 -26
  96. package/lib/modules/Order/payment-utils.js +0 -224
  97. package/lib/utils/payment-number.d.ts +0 -9
  98. package/lib/utils/payment-number.js +0 -64
@@ -37,8 +37,6 @@ var import_types = require("./types");
37
37
  var import_utils = require("./utils");
38
38
  var import_utils2 = require("../Product/utils");
39
39
  var import_dayjs = __toESM(require("dayjs"));
40
- var import_payment_utils = require("./payment-utils");
41
- var import_payment_number = require("../../utils/payment-number");
42
40
  var import_cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
43
41
  var import_utils3 = require("../../solution/ScanOrder/utils");
44
42
  var import_manualProductDiscount = require("./utils/manualProductDiscount");
@@ -85,11 +83,6 @@ function isPaidPaymentRecord(payment) {
85
83
  function isCommittedVoucherPaymentRecord(payment) {
86
84
  return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) !== "voided" && (hasSyncedOrderPaymentRecord(payment) || isPaidPaymentRecord(payment));
87
85
  }
88
- function getVoucherPaymentLifecycleKey(payment) {
89
- if (!isVoucherPaymentRecord(payment))
90
- return null;
91
- return `${String(payment.voucher_id)}::${String(payment.status || "")}`;
92
- }
93
86
  var OrderModule = class extends import_BaseModule.BaseModule {
94
87
  constructor(name, version) {
95
88
  super(name || "order", version);
@@ -320,11 +313,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
320
313
  this.store.availableWalletIds = [];
321
314
  }
322
315
  this.request = this.core.getPlugin("request");
323
- this.appPlugin = this.core.getPlugin("app");
324
- if (!this.appPlugin) {
316
+ const appPlugin = this.core.getPlugin("app");
317
+ if (!appPlugin) {
325
318
  throw new Error("Order 模块需要 app 插件支持");
326
319
  }
327
- const app = this.appPlugin.getApp();
320
+ const app = appPlugin.getApp();
328
321
  this.logger = app.logger;
329
322
  this.window = this.core.getPlugin("window");
330
323
  const otherParams = options.otherParams || {};
@@ -1060,40 +1053,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1060
1053
  const depositPaidAmount = this.calculateDepositPaidAmount(tempOrder.payments || []);
1061
1054
  return depositPaidAmount.lt(depositAmount) ? "deposit" : "normal";
1062
1055
  }
1063
- getPaymentNumberAppData(key) {
1064
- var _a, _b, _c, _d, _e;
1065
- const appPlugin = this.appPlugin;
1066
- if (!appPlugin)
1067
- return void 0;
1068
- const getData = (_a = appPlugin.getData) == null ? void 0 : _a.call(appPlugin);
1069
- if (typeof getData === "function")
1070
- return getData(key);
1071
- const app = appPlugin.getApp();
1072
- const coreData = (_e = (_c = (_b = app == null ? void 0 : app.models) == null ? void 0 : _b.getStore) == null ? void 0 : (_d = _c.call(_b)).getDataByModel) == null ? void 0 : _e.call(_d, "core", "core");
1073
- return coreData == null ? void 0 : coreData[key];
1074
- }
1075
- getPaymentNumberDevicePrefixSync() {
1076
- return (0, import_payment_number.resolvePaymentNumberDevicePrefixFromDeviceId)(
1077
- (key) => this.getPaymentNumberAppData(key)
1078
- );
1079
- }
1080
- getPaymentNumberDevicePrefixAsync() {
1081
- return (0, import_payment_number.resolvePaymentNumberDevicePrefix)(
1082
- (key) => this.getPaymentNumberAppData(key)
1083
- );
1084
- }
1085
1056
  normalizePaymentSource(payment, options) {
1086
1057
  const paymentRecord = payment;
1087
1058
  const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
1088
- const normalized = (0, import_payment_utils.ensureOrderPaymentNumber)(
1089
- {
1090
- ...paymentRecord,
1091
- metadata,
1092
- origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
1093
- },
1094
- (options == null ? void 0 : options.devicePrefix) || this.getPaymentNumberDevicePrefixSync(),
1095
- import_utils.createUuidV4
1096
- );
1059
+ if (!metadata.unique_payment_number) {
1060
+ metadata.unique_payment_number = (0, import_utils.createUuidV4)();
1061
+ }
1062
+ const normalized = {
1063
+ ...paymentRecord,
1064
+ metadata,
1065
+ origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
1066
+ };
1097
1067
  if (paymentRecord.status !== void 0) {
1098
1068
  normalized.status = paymentRecord.status;
1099
1069
  } else if ((options == null ? void 0 : options.defaultPaid) !== false) {
@@ -2514,36 +2484,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2514
2484
  * 用一组支付来源覆盖当前订单支付项。
2515
2485
  *
2516
2486
  * 入参允许来自 PaymentModule 的 PaymentItem,内部统一映射为 Sales 协议:
2517
- * 新支付来源的 uuid 会作为 payment_number 的唯一号段,id -> custom_payment_id,
2487
+ * uuid -> metadata.unique_payment_number,id -> custom_payment_id,
2518
2488
  * isSynced 等运行态字段不会进入 tempOrder.payments。
2519
2489
  */
2520
2490
  setOrderPayments(payments) {
2521
2491
  const tempOrder = this.ensureTempOrder();
2522
- tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(
2523
- (payments || []).map((payment) => this.normalizePaymentSource(payment, { defaultPaid: false }))
2524
- );
2492
+ tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(payments);
2525
2493
  this.persistTempOrder();
2526
2494
  return tempOrder.payments;
2527
2495
  }
2528
- /** 同步兼容入口:按调用当下的 device_id 或 LOCAL 生成支付编号。 */
2496
+ /** 追加单个支付项,并立即持久化当前 tempOrder。 */
2529
2497
  addOrderPayment(payment) {
2530
- const hasPaymentNumber = String(
2531
- payment.payment_number || ""
2532
- ).trim() !== "";
2533
- return this.addOrderPaymentWithDevicePrefix(
2534
- payment,
2535
- hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
2536
- );
2537
- }
2538
- /** 异步入口:创建支付项时读取最新 IoT 设备短号。 */
2539
- async addOrderPaymentAsync(payment) {
2540
- const hasPaymentNumber = String(
2541
- payment.payment_number || ""
2542
- ).trim() !== "";
2543
- const devicePrefix = hasPaymentNumber ? "LOCAL" : await this.getPaymentNumberDevicePrefixAsync();
2544
- return this.addOrderPaymentWithDevicePrefix(payment, devicePrefix);
2545
- }
2546
- addOrderPaymentWithDevicePrefix(payment, devicePrefix) {
2547
2498
  this.logInfo("addOrderPayment", {
2548
2499
  payment
2549
2500
  });
@@ -2556,7 +2507,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2556
2507
  type: orderPaymentType,
2557
2508
  order_payment_type: orderPaymentType
2558
2509
  },
2559
- { defaultPaid: true, devicePrefix }
2510
+ { defaultPaid: true }
2560
2511
  )
2561
2512
  ]);
2562
2513
  tempOrder.payments = [...tempOrder.payments || [], ...mapped];
@@ -2569,55 +2520,57 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2569
2520
  return tempOrder.payments;
2570
2521
  }
2571
2522
  /**
2572
- * 默认按支付唯一号精确更新;仅显式指定 legacy 时兼容历史支付标识。
2573
- * metadata 与 transactions 会分别合并,避免覆盖支付会话号和已有交易记录。
2523
+ * 按支付唯一号、后端支付 ID、自定义支付方式 ID 或旧 uuid 更新支付项。
2524
+ *
2525
+ * 该方法服务 PaymentModal 的 void / 编辑场景;更新 metadata 时会做浅合并,
2526
+ * 避免覆盖 unique_payment_number、现金实付/找零等已有元数据。
2574
2527
  */
2575
- async updateOrderPayment(paymentIdentity, updates, options = {}) {
2528
+ updateOrderPayment(paymentIdentity, updates) {
2576
2529
  const tempOrder = this.ensureTempOrder();
2577
2530
  const identity = String(paymentIdentity);
2578
- const matchMode = options.matchBy === "compat" || options.matchBy === "legacy" ? "compat" : "payment_number";
2579
- const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2580
- tempOrder.payments || [],
2581
- identity,
2582
- matchMode
2583
- );
2584
- if (!matchedPayment) {
2585
- throw new Error(`未找到支付项: ${identity}`);
2586
- }
2587
- let updatedPayment = null;
2588
- tempOrder.payments = (tempOrder.payments || []).map((payment, index) => {
2589
- if (index !== matchedPayment.index)
2531
+ tempOrder.payments = (tempOrder.payments || []).map((payment) => {
2532
+ var _a;
2533
+ const uniquePaymentNumber = (_a = payment == null ? void 0 : payment.metadata) == null ? void 0 : _a.unique_payment_number;
2534
+ const orderPaymentId = payment == null ? void 0 : payment.order_payment_id;
2535
+ const customPaymentId = payment == null ? void 0 : payment.custom_payment_id;
2536
+ const uuid = payment == null ? void 0 : payment.uuid;
2537
+ const matched = [
2538
+ uniquePaymentNumber,
2539
+ orderPaymentId,
2540
+ customPaymentId,
2541
+ uuid
2542
+ ].some((value) => value !== void 0 && String(value) === identity);
2543
+ if (!matched)
2590
2544
  return payment;
2591
- const nextPayment = (0, import_payment_utils.mergeOrderPaymentRecord)(payment, {
2545
+ return {
2546
+ ...payment,
2592
2547
  ...updates,
2593
- updated_at: updates.updated_at || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2594
- });
2595
- updatedPayment = nextPayment;
2596
- return nextPayment;
2548
+ metadata: {
2549
+ ...payment.metadata || {},
2550
+ ...updates.metadata || {}
2551
+ }
2552
+ };
2597
2553
  });
2598
2554
  this.persistTempOrder();
2599
- const summary = await this.recalculateSummary({ createIfMissing: true });
2600
- this.persistTempOrder();
2601
- const payments = tempOrder.payments;
2602
- return {
2603
- updated: true,
2604
- payment: payments[matchedPayment.index] || updatedPayment,
2605
- payments,
2606
- summary
2607
- };
2555
+ return tempOrder.payments;
2608
2556
  }
2609
2557
  /** 从当前订单支付项中移除指定支付项。 */
2610
2558
  deleteOrderPayment(paymentIdentity) {
2611
2559
  const tempOrder = this.ensureTempOrder();
2612
2560
  const identity = String(paymentIdentity);
2613
- const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2614
- tempOrder.payments || [],
2615
- identity,
2616
- "compat"
2617
- );
2618
- if (!matchedPayment)
2619
- return tempOrder.payments;
2620
- tempOrder.payments = (tempOrder.payments || []).filter((_, index) => index !== matchedPayment.index);
2561
+ tempOrder.payments = (tempOrder.payments || []).filter((payment) => {
2562
+ var _a;
2563
+ const uniquePaymentNumber = (_a = payment == null ? void 0 : payment.metadata) == null ? void 0 : _a.unique_payment_number;
2564
+ const orderPaymentId = payment == null ? void 0 : payment.order_payment_id;
2565
+ const customPaymentId = payment == null ? void 0 : payment.custom_payment_id;
2566
+ const uuid = payment == null ? void 0 : payment.uuid;
2567
+ return ![
2568
+ uniquePaymentNumber,
2569
+ orderPaymentId,
2570
+ customPaymentId,
2571
+ uuid
2572
+ ].some((value) => value !== void 0 && String(value) === identity);
2573
+ });
2621
2574
  this.persistTempOrder();
2622
2575
  return tempOrder.payments;
2623
2576
  }
@@ -2726,10 +2679,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2726
2679
  payments.map(
2727
2680
  (payment) => this.normalizePaymentSource(
2728
2681
  normalizeVoucherPaymentStatus(withVoucherPaymentType(payment)),
2729
- {
2730
- defaultPaid: false,
2731
- devicePrefix: options == null ? void 0 : options.devicePrefix
2732
- }
2682
+ { defaultPaid: false }
2733
2683
  )
2734
2684
  )
2735
2685
  ).filter((payment) => {
@@ -2751,15 +2701,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2751
2701
  const committedVoucherPaymentIds = new Set(
2752
2702
  committedVoucherPayments.filter((payment) => hasSyncedOrderPaymentRecord(payment)).map((payment) => String(payment.order_payment_id))
2753
2703
  );
2754
- const committedVoucherLifecycleKeys = new Set(
2755
- committedVoucherPayments.map((payment) => getVoucherPaymentLifecycleKey(payment)).filter((key) => key !== null)
2704
+ const committedVoucherIds = new Set(
2705
+ committedVoucherPayments.map((payment) => String(payment.voucher_id))
2756
2706
  );
2757
2707
  const replaceableVouchers = mappedVouchers.filter((payment) => {
2758
2708
  if (hasSyncedOrderPaymentRecord(payment) && committedVoucherPaymentIds.has(String(payment.order_payment_id))) {
2759
2709
  return false;
2760
2710
  }
2761
- const lifecycleKey = getVoucherPaymentLifecycleKey(payment);
2762
- if (lifecycleKey && committedVoucherLifecycleKeys.has(lifecycleKey)) {
2711
+ if (payment.voucher_id !== void 0 && committedVoucherIds.has(String(payment.voucher_id))) {
2763
2712
  return false;
2764
2713
  }
2765
2714
  return true;
@@ -2781,14 +2730,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2781
2730
  });
2782
2731
  return tempOrder.payments;
2783
2732
  }
2784
- async updateVoucherOrderPaymentsAsync(payments, options) {
2785
- const needsPaymentNumber = (payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
2786
- const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
2787
- return this.updateVoucherOrderPayments(payments, {
2788
- ...options,
2789
- devicePrefix
2790
- });
2791
- }
2792
2733
  async shouldMergeProductToOrder(params) {
2793
2734
  var _a;
2794
2735
  const onBeforeMergeProductToOrder = (_a = this.orderHooks) == null ? void 0 : _a.onBeforeMergeProductToOrder;
@@ -2848,8 +2789,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2848
2789
  * @example
2849
2790
  * await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
2850
2791
  */
2851
- async appendProductLineToTempOrder(tempOrder, product, booking) {
2852
- var _a, _b;
2792
+ async appendProductLineToTempOrder(tempOrder, product, booking, options) {
2793
+ var _a, _b, _c, _d;
2853
2794
  const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
2854
2795
  const productToAdd = (linked == null ? void 0 : linked.product) || product;
2855
2796
  const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
@@ -2860,7 +2801,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2860
2801
  productToAdd,
2861
2802
  (0, import_utils3.normalizeOrderProduct)(productToAdd)
2862
2803
  );
2863
- const incomingBookingUid = productToAdd.booking_uid ?? ((_a = productToAdd.metadata) == null ? void 0 : _a.booking_uid);
2804
+ const isWeighingProduct = Number(((_a = normalizedIncoming.product_sku) == null ? void 0 : _a.open_sold_weight) || 0) === 1;
2805
+ const netWeight = Number((_b = normalizedIncoming.product_sku) == null ? void 0 : _b.net_weight);
2806
+ if (isWeighingProduct && (!Number.isFinite(netWeight) || netWeight <= 0)) {
2807
+ throw new Error("[Order] 称重商品净重必须大于 0");
2808
+ }
2809
+ const incomingBookingUid = productToAdd.booking_uid ?? ((_c = productToAdd.metadata) == null ? void 0 : _c.booking_uid);
2864
2810
  if (incomingBookingUid !== void 0 && incomingBookingUid !== null && String(incomingBookingUid) !== "") {
2865
2811
  normalizedIncoming.booking_uid = String(incomingBookingUid);
2866
2812
  normalizedIncoming.metadata = {
@@ -2876,7 +2822,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2876
2822
  );
2877
2823
  const hasIncomingProductNote = this.hasOrderProductLineNote(normalizedIncoming);
2878
2824
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
2879
- const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
2825
+ const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid || isWeighingProduct;
2880
2826
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
2881
2827
  var _a2;
2882
2828
  if (this.hasGoodPassDiscount(item))
@@ -2925,10 +2871,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2925
2871
  booking_uid: linked.bookingUid
2926
2872
  };
2927
2873
  }
2928
- tempOrder.products = [...tempOrder.products, normalizedIncoming];
2874
+ const insertAtIndex = options == null ? void 0 : options.insertAtIndex;
2875
+ if (Number.isInteger(insertAtIndex) && Number(insertAtIndex) >= 0 && Number(insertAtIndex) < tempOrder.products.length) {
2876
+ tempOrder.products = [
2877
+ ...tempOrder.products.slice(0, insertAtIndex),
2878
+ normalizedIncoming,
2879
+ ...tempOrder.products.slice(insertAtIndex)
2880
+ ];
2881
+ } else {
2882
+ tempOrder.products = [...tempOrder.products, normalizedIncoming];
2883
+ }
2929
2884
  } else {
2930
2885
  const targetProduct = matchedProduct;
2931
- const targetUid = (_b = targetProduct.metadata) == null ? void 0 : _b.unique_identification_number;
2886
+ const targetUid = (_d = targetProduct.metadata) == null ? void 0 : _d.unique_identification_number;
2932
2887
  const normalizedProduct = (0, import_utils.mergeOrderProductDisplayFields)(
2933
2888
  targetProduct,
2934
2889
  (0, import_utils3.normalizeOrderProduct)({
@@ -2984,6 +2939,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2984
2939
  tempOrder.products[matchedIndex],
2985
2940
  targetUid
2986
2941
  );
2942
+ if (matchedIndex !== tempOrder.products.length - 1) {
2943
+ const mergedProduct = tempOrder.products[matchedIndex];
2944
+ tempOrder.products = [
2945
+ ...tempOrder.products.slice(0, matchedIndex),
2946
+ ...tempOrder.products.slice(matchedIndex + 1),
2947
+ mergedProduct
2948
+ ];
2949
+ }
2987
2950
  }
2988
2951
  if (linked) {
2989
2952
  tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
@@ -2996,8 +2959,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2996
2959
  * await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
2997
2960
  * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
2998
2961
  */
2999
- async addProductToOrder(product, booking) {
2962
+ async addProductToOrder(product, booking, options) {
3000
2963
  const tempOrder = this.ensureTempOrder();
2964
+ const insertAfterProductUid = options == null ? void 0 : options.insertAfterProductUid;
2965
+ const anchorIndex = booking && insertAfterProductUid ? tempOrder.products.findIndex((line) => {
2966
+ var _a;
2967
+ const uid = ((_a = line.metadata) == null ? void 0 : _a.unique_identification_number) || line.unique_identification_number;
2968
+ return uid !== void 0 && uid !== null && String(uid) === String(insertAfterProductUid);
2969
+ }) : -1;
2970
+ let insertAtIndex = anchorIndex >= 0 ? anchorIndex + 1 : void 0;
3001
2971
  if (booking) {
3002
2972
  const productRecord = product;
3003
2973
  const splitCount = (0, import_utils3.getSafeProductNum)(
@@ -3011,14 +2981,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3011
2981
  await this.appendProductLineToTempOrder(
3012
2982
  tempOrder,
3013
2983
  singleLine,
3014
- (0, import_lodash_es.cloneDeep)(booking)
2984
+ (0, import_lodash_es.cloneDeep)(booking),
2985
+ { insertAtIndex }
3015
2986
  );
2987
+ if (insertAtIndex !== void 0)
2988
+ insertAtIndex += 1;
3016
2989
  }
3017
2990
  await this.finalizeProductOrderMutation(tempOrder);
3018
2991
  return tempOrder.products;
3019
2992
  }
3020
2993
  }
3021
- await this.appendProductLineToTempOrder(tempOrder, product, booking);
2994
+ await this.appendProductLineToTempOrder(
2995
+ tempOrder,
2996
+ product,
2997
+ booking,
2998
+ { insertAtIndex }
2999
+ );
3022
3000
  await this.finalizeProductOrderMutation(tempOrder);
3023
3001
  this.logInfo("addProductToOrder success", {
3024
3002
  product_id: product.product_id,
@@ -3499,7 +3477,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3499
3477
  * @example
3500
3478
  * await order.removeProductsFromOrder([identityA, identityB]);
3501
3479
  */
3502
- async removeProductsFromOrder(identities) {
3480
+ async removeProductsFromOrder(identities, options) {
3503
3481
  var _a, _b, _c, _d;
3504
3482
  const tempOrder = this.ensureTempOrder();
3505
3483
  if (!identities.length) {
@@ -3507,6 +3485,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3507
3485
  }
3508
3486
  const productsBeforeRemove = tempOrder.products || [];
3509
3487
  const bookingsBeforeRemove = tempOrder.bookings || [];
3488
+ const preserveDisplayPosition = options == null ? void 0 : options.preserveDisplayPosition;
3489
+ const anchorIndex = preserveDisplayPosition ? productsBeforeRemove.findIndex((item) => {
3490
+ var _a2;
3491
+ const uid = ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number;
3492
+ return uid !== void 0 && uid !== null && String(uid) === String(preserveDisplayPosition.anchorProductUid);
3493
+ }) : -1;
3494
+ const productsAfterAnchor = anchorIndex >= 0 ? productsBeforeRemove.slice(anchorIndex + 1) : [];
3510
3495
  const matchedProducts = productsBeforeRemove.filter((item) => {
3511
3496
  return identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
3512
3497
  });
@@ -3547,14 +3532,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3547
3532
  return !(isAddTimeProduct && lineBookingUid !== void 0 && lineBookingUid !== null && linkedBookingUidsToRemove.has(String(lineBookingUid)));
3548
3533
  });
3549
3534
  }
3535
+ if (preserveDisplayPosition && anchorIndex >= 0) {
3536
+ const remainingProductIndex = tempOrder.products.findIndex((item) => {
3537
+ var _a2;
3538
+ const uid = ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number;
3539
+ return uid !== void 0 && uid !== null && String(uid) === String(preserveDisplayPosition.remainingProductUid);
3540
+ });
3541
+ if (remainingProductIndex >= 0) {
3542
+ const remainingProduct = tempOrder.products[remainingProductIndex];
3543
+ const nextProduct = productsAfterAnchor.find(
3544
+ (item) => tempOrder.products.includes(item)
3545
+ );
3546
+ const productsWithoutRemaining = [
3547
+ ...tempOrder.products.slice(0, remainingProductIndex),
3548
+ ...tempOrder.products.slice(remainingProductIndex + 1)
3549
+ ];
3550
+ const nextProductIndex = nextProduct ? productsWithoutRemaining.indexOf(nextProduct) : -1;
3551
+ tempOrder.products = nextProductIndex >= 0 ? [
3552
+ ...productsWithoutRemaining.slice(0, nextProductIndex),
3553
+ remainingProduct,
3554
+ ...productsWithoutRemaining.slice(nextProductIndex)
3555
+ ] : [...productsWithoutRemaining, remainingProduct];
3556
+ }
3557
+ }
3550
3558
  await this.finalizeAfterProductsMutation(tempOrder);
3551
3559
  this.logInfo("removeProductsFromOrder success", {
3552
3560
  identities
3553
3561
  });
3554
3562
  return tempOrder.products;
3555
3563
  }
3556
- async removeProductFromOrder(identity) {
3557
- return this.removeProductsFromOrder([identity]);
3564
+ async removeProductFromOrder(identity, options) {
3565
+ return this.removeProductsFromOrder([identity], options);
3558
3566
  }
3559
3567
  /**
3560
3568
  * 仅清空购物车行(products / bookings),不重置整单。
@@ -3619,38 +3627,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3619
3627
  await this.saveDraft();
3620
3628
  return tempOrder;
3621
3629
  }
3622
- async saveTempOrderAsDraft(params) {
3623
- var _a, _b, _c, _d, _e;
3624
- const tempOrder = this.ensureTempOrder();
3625
- this.ensureExternalSaleNumber(tempOrder);
3626
- this.persistTempOrder();
3627
- const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
3628
- const payload = (0, import_utils.buildSubmitPayload)({
3629
- tempOrder,
3630
- cacheId: (params == null ? void 0 : params.cacheId) ?? this.cacheId,
3631
- platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
3632
- businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
3633
- channel: params == null ? void 0 : params.channel,
3634
- type: (params == null ? void 0 : params.type) ?? ((_d = this.otherParams) == null ? void 0 : _d.type),
3635
- summary: latestSummary,
3636
- enhance: params == null ? void 0 : params.enhancePayload
3637
- });
3638
- if (!payload.created_at) {
3639
- payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
3640
- }
3641
- payload.need_sync = 0;
3642
- payload.is_draft_order = 1;
3643
- this.logInfo("saveTempOrderAsDraft calling sales draft", {
3644
- orderId: payload.order_id,
3645
- externalSaleNumber: payload.external_sale_number,
3646
- productsCount: ((_e = payload.products) == null ? void 0 : _e.length) || 0
3647
- });
3648
- return this.request.post("/order/sales/draft", payload, {
3649
- osServer: true,
3650
- customToast: () => {
3651
- }
3652
- });
3653
- }
3654
3630
  /**
3655
3631
  * 提交当前 Sales tempOrder。
3656
3632
  *
@@ -3851,13 +3827,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3851
3827
  }
3852
3828
  async syncPaymentsToOrder(params) {
3853
3829
  const tempOrder = this.ensureTempOrder();
3854
- const needsPaymentNumber = (params.payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
3855
- const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
3856
3830
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
3857
- (params.payments || []).map((payment) => this.normalizePaymentSource(payment, {
3858
- defaultPaid: false,
3859
- devicePrefix
3860
- }))
3831
+ params.payments || []
3861
3832
  );
3862
3833
  const shouldConfirmPendingVoucherPayments = params.confirmPendingVoucherPayments ?? params.submitWhenPaid === true;
3863
3834
  const effectivePayments = shouldConfirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : params.confirmPendingVoucherPayments === false ? this.discardPendingVoucherPaymentsFromList(mappedPayments) : mappedPayments;
@@ -4233,12 +4204,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4233
4204
  }
4234
4205
  }
4235
4206
  const nextTempOrder = this.normalizeTempOrderForRuntime(raw, { makeEditMark: true });
4236
- const sourceLastOrderInfo = raw.lastOrderInfo || raw;
4237
- const isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
4238
- const syntheticIdentityOptions = {
4239
- isDraftOrder,
4240
- externalSaleNumber: nextTempOrder.external_sale_number
4241
- };
4242
4207
  const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
4243
4208
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
4244
4209
  this.store.tempOrder = nextTempOrder;
@@ -4259,14 +4224,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4259
4224
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
4260
4225
  }
4261
4226
  };
4262
- this.store.lastOrderInfo = this.withoutSyntheticDraftOrderIdForRuntime(
4263
- sourceLastOrderInfo,
4264
- syntheticIdentityOptions
4265
- );
4266
- const hadSyntheticDraftOrderId = this.isSyntheticDraftOrderIdForRuntime(raw, syntheticIdentityOptions) || this.isSyntheticDraftOrderIdForRuntime(sourceLastOrderInfo, syntheticIdentityOptions);
4267
- if (hadSyntheticDraftOrderId && this.store.syncState !== "submitting") {
4268
- this.store.syncState = "local";
4269
- }
4227
+ this.store.lastOrderInfo = sourceRaw.lastOrderInfo || sourceRaw;
4270
4228
  const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
4271
4229
  const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
4272
4230
  const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
@@ -4379,13 +4337,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4379
4337
  }
4380
4338
  normalizeTempOrderForRuntime(raw, options) {
4381
4339
  var _a, _b;
4382
- const runtimeRaw = this.withoutSyntheticDraftOrderIdForRuntime(raw);
4383
4340
  const nextTempOrder = {
4384
4341
  ...this.createDefaultTempOrderInstance(),
4385
- ...runtimeRaw || {}
4342
+ ...raw || {}
4386
4343
  };
4387
- if ((nextTempOrder.order_id === void 0 || nextTempOrder.order_id === null) && (runtimeRaw == null ? void 0 : runtimeRaw.id) !== void 0 && (runtimeRaw == null ? void 0 : runtimeRaw.id) !== null) {
4388
- nextTempOrder.order_id = runtimeRaw.id;
4344
+ if ((nextTempOrder.order_id === void 0 || nextTempOrder.order_id === null) && (raw == null ? void 0 : raw.id) !== void 0 && (raw == null ? void 0 : raw.id) !== null) {
4345
+ nextTempOrder.order_id = raw.id;
4389
4346
  }
4390
4347
  delete nextTempOrder.summary;
4391
4348
  delete nextTempOrder.lastOrderInfo;
@@ -4453,22 +4410,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4453
4410
  nextTempOrder.vouchers = raw.vouchers || [];
4454
4411
  return nextTempOrder;
4455
4412
  }
4456
- isSyntheticDraftOrderIdForRuntime(record, options) {
4457
- const isDraftOrder = (options == null ? void 0 : options.isDraftOrder) ?? Number((record == null ? void 0 : record.is_draft_order) || 0) === 1;
4458
- const externalSaleNumber = (record == null ? void 0 : record.external_sale_number) ?? (options == null ? void 0 : options.externalSaleNumber);
4459
- const orderId = record == null ? void 0 : record.order_id;
4460
- return Boolean(
4461
- isDraftOrder && orderId !== void 0 && orderId !== null && orderId !== "" && externalSaleNumber !== void 0 && externalSaleNumber !== null && externalSaleNumber !== "" && String(orderId) === String(externalSaleNumber)
4462
- );
4463
- }
4464
- withoutSyntheticDraftOrderIdForRuntime(record, options) {
4465
- if (!this.isSyntheticDraftOrderIdForRuntime(record, options))
4466
- return record;
4467
- return {
4468
- ...record,
4469
- order_id: null
4470
- };
4471
- }
4472
4413
  hydrateLinkedBookingIdentity(tempOrder) {
4473
4414
  const bookingUidByProductUid = /* @__PURE__ */ new Map();
4474
4415
  const productByUid = /* @__PURE__ */ new Map();