@pisell/pisellos 2.2.188 → 2.2.190

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 (36) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/Order/index.d.ts +1 -0
  3. package/dist/modules/Order/index.js +53 -45
  4. package/dist/modules/Order/types.d.ts +2 -0
  5. package/dist/modules/Order/utils.js +3 -1
  6. package/dist/solution/BaseSales/index.js +61 -53
  7. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -2
  8. package/dist/solution/BookingByStep/index.d.ts +1 -1
  9. package/dist/solution/BookingTicket/index.d.ts +16 -1
  10. package/dist/solution/BookingTicket/index.js +117 -6
  11. package/dist/solution/BookingTicket/types.d.ts +48 -0
  12. package/dist/solution/BookingTicket/types.js +5 -1
  13. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  14. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +394 -0
  15. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  16. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +56 -0
  17. package/dist/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  18. package/dist/solution/BookingTicket/utils/scan/scanProductValues.js +150 -0
  19. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  20. package/lib/modules/Order/index.d.ts +1 -0
  21. package/lib/modules/Order/index.js +15 -10
  22. package/lib/modules/Order/types.d.ts +2 -0
  23. package/lib/modules/Order/utils.js +1 -0
  24. package/lib/solution/BaseSales/index.js +12 -4
  25. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +11 -2
  26. package/lib/solution/BookingByStep/index.d.ts +1 -1
  27. package/lib/solution/BookingTicket/index.d.ts +16 -1
  28. package/lib/solution/BookingTicket/index.js +56 -0
  29. package/lib/solution/BookingTicket/types.d.ts +48 -0
  30. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +36 -0
  31. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +166 -0
  32. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +32 -0
  33. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +51 -0
  34. package/lib/solution/BookingTicket/utils/scan/scanProductValues.d.ts +21 -0
  35. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +127 -0
  36. package/package.json +1 -1
@@ -0,0 +1,150 @@
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 _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
3
+ 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); }
4
+ 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; }
5
+ 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; }
6
+ 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; }
7
+ 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; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
+ 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); }
10
+ /**
11
+ * 扫码商品条码预选规格纯函数(对齐 ticketBooking addServiceVariant/utils)。
12
+ */
13
+
14
+ /** 套餐商品 */
15
+ export function isScanProductBundle(item) {
16
+ return ((item === null || item === void 0 ? void 0 : item.bundle_group_count) || 0) > 0;
17
+ }
18
+
19
+ /** 单规格 / 选项组商品 */
20
+ export function isScanProductOption(item) {
21
+ var _item$option_group;
22
+ return ((item === null || item === void 0 ? void 0 : item.option_group_count) || 0) > 0 || ((item === null || item === void 0 || (_item$option_group = item.option_group) === null || _item$option_group === void 0 ? void 0 : _item$option_group.length) || 0) > 0;
23
+ }
24
+ function formatVariantGroupTitle(title) {
25
+ var variantGroup = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
26
+ try {
27
+ return variantGroup.map(function (group) {
28
+ var value = title === null || title === void 0 ? void 0 : title[group === null || group === void 0 ? void 0 : group.position_id];
29
+ return value ? "".concat((group === null || group === void 0 ? void 0 : group.name) || '-', ": ").concat(value) : '';
30
+ }).filter(Boolean).join(', ');
31
+ } catch (_unused) {
32
+ return '';
33
+ }
34
+ }
35
+ function formatDataKey(data) {
36
+ var _next$option, _next$bundle;
37
+ var next = _objectSpread({}, data);
38
+ var key = "".concat(next.product_id);
39
+ var rowKey = key;
40
+ if (next.product_variant_id) {
41
+ var str = "_".concat(next.product_variant_id);
42
+ key += str;
43
+ rowKey += str;
44
+ }
45
+ if (next !== null && next !== void 0 && (_next$option = next.option) !== null && _next$option !== void 0 && _next$option.length) {
46
+ var _iterator = _createForOfIteratorHelper(next.option),
47
+ _step;
48
+ try {
49
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
50
+ var item = _step.value;
51
+ var _str = "_".concat(item.option_group_id, "_").concat(item.product_option_item_id);
52
+ key += _str;
53
+ rowKey += "".concat(_str, "_").concat(item.quantity || item.num);
54
+ }
55
+ } catch (err) {
56
+ _iterator.e(err);
57
+ } finally {
58
+ _iterator.f();
59
+ }
60
+ }
61
+ if (next !== null && next !== void 0 && (_next$bundle = next.bundle) !== null && _next$bundle !== void 0 && _next$bundle.length) {
62
+ var _iterator2 = _createForOfIteratorHelper(next.bundle),
63
+ _step2;
64
+ try {
65
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
66
+ var _item = _step2.value;
67
+ var _str2 = "_".concat(_item.group_id, "_").concat(_item.bundle_product_id);
68
+ key += _str2;
69
+ rowKey += "".concat(_str2, "_").concat(_item.quantity || _item.num);
70
+ if (_item !== null && _item !== void 0 && _item.option) {
71
+ var _iterator3 = _createForOfIteratorHelper(_item.option),
72
+ _step3;
73
+ try {
74
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
75
+ var opt = _step3.value;
76
+ var optStr = "_".concat(opt.option_group_id, "_").concat(opt.product_option_item_id);
77
+ key += optStr;
78
+ rowKey += "".concat(optStr, "_").concat(opt.quantity || opt.num);
79
+ }
80
+ } catch (err) {
81
+ _iterator3.e(err);
82
+ } finally {
83
+ _iterator3.f();
84
+ }
85
+ }
86
+ }
87
+ } catch (err) {
88
+ _iterator2.e(err);
89
+ } finally {
90
+ _iterator2.f();
91
+ }
92
+ }
93
+ if (next !== null && next !== void 0 && next.session) {
94
+ var _next$session;
95
+ var _str3 = "_".concat((_next$session = next.session) === null || _next$session === void 0 ? void 0 : _next$session.key);
96
+ key += _str3;
97
+ rowKey += _str3;
98
+ }
99
+ if (next !== null && next !== void 0 && next.schedule) {
100
+ var _next$schedule;
101
+ var _str4 = "_".concat((_next$schedule = next.schedule) === null || _next$schedule === void 0 ? void 0 : _next$schedule.key);
102
+ key += _str4;
103
+ rowKey += _str4;
104
+ }
105
+ next.key = key;
106
+ next.rowKey = rowKey;
107
+ return next;
108
+ }
109
+
110
+ /**
111
+ * 根据条码匹配 variant,生成 cartDetailValue(对齐 ticketBooking `genValues`)。
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const values = genScanProductValues(catalogItem, '6901234567890');
116
+ * const itemWithSelection = { ...catalogItem, cartDetailValue: values };
117
+ * ```
118
+ */
119
+ export function genScanProductValues(item, code) {
120
+ var _item$variant_group, _item$option_group2;
121
+ var params = {
122
+ bundle: [],
123
+ option: [],
124
+ product_id: item.id,
125
+ product_variant_id: 0,
126
+ quantity: 1,
127
+ rowKey: '',
128
+ session: null
129
+ };
130
+ if (item !== null && item !== void 0 && (_item$variant_group = item.variant_group) !== null && _item$variant_group !== void 0 && _item$variant_group.length || item !== null && item !== void 0 && (_item$option_group2 = item.option_group) !== null && _item$option_group2 !== void 0 && _item$option_group2.length) {
131
+ var variantItem = (item.variant || []).find(function (v) {
132
+ return (v === null || v === void 0 ? void 0 : v.code) === code || (v === null || v === void 0 ? void 0 : v.barcode) === code;
133
+ });
134
+ if (variantItem) {
135
+ params.price = Number((variantItem === null || variantItem === void 0 ? void 0 : variantItem.price) || 0);
136
+ params.product_variant_id = variantItem.id;
137
+ params.product_option_string = formatVariantGroupTitle(variantItem === null || variantItem === void 0 ? void 0 : variantItem.title, (item === null || item === void 0 ? void 0 : item.variant_group) || []);
138
+ }
139
+ }
140
+ return formatDataKey(params);
141
+ }
142
+
143
+ /**
144
+ * 统计条码命中的 variant 数量(多命中时需弹窗选择)。
145
+ */
146
+ export function countScanVariantMatches(item, code) {
147
+ return ((item === null || item === void 0 ? void 0 : item.variant) || []).filter(function (v) {
148
+ return (v === null || v === void 0 ? void 0 : v.code) === code || (v === null || v === void 0 ? void 0 : v.barcode) === code;
149
+ }).length;
150
+ }
@@ -0,0 +1,49 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/model/strategy/adapter/promotion/index.ts
30
+ var promotion_exports = {};
31
+ __export(promotion_exports, {
32
+ BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
33
+ PromotionAdapter: () => import_adapter.PromotionAdapter,
34
+ PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
35
+ X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
36
+ default: () => import_adapter2.default
37
+ });
38
+ module.exports = __toCommonJS(promotion_exports);
39
+ var import_evaluator = require("./evaluator");
40
+ var import_adapter = require("./adapter");
41
+ var import_adapter2 = __toESM(require("./adapter"));
42
+ var import_examples = require("./examples");
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ BUY_X_GET_Y_FREE_STRATEGY,
46
+ PromotionAdapter,
47
+ PromotionEvaluator,
48
+ X_ITEMS_FOR_Y_PRICE_STRATEGY
49
+ });
@@ -143,6 +143,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
143
143
  private saveDraftInBackground;
144
144
  private hydrateTempOrderFromLocalRecord;
145
145
  private extractOrderIdFromSubmitResult;
146
+ private calculatePaymentEffectiveAmount;
146
147
  private calculatePaymentTotal;
147
148
  private normalizePaymentSource;
148
149
  private updateTempOrderPaymentStatus;
@@ -690,13 +690,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
690
690
  var _a, _b;
691
691
  return ((_a = result == null ? void 0 : result.data) == null ? void 0 : _a.order_id) ?? (result == null ? void 0 : result.order_id) ?? ((_b = result == null ? void 0 : result.data) == null ? void 0 : _b.id) ?? (result == null ? void 0 : result.id) ?? null;
692
692
  }
693
+ calculatePaymentEffectiveAmount(payment) {
694
+ const amount = new import_decimal.default(payment.amount || 0).minus(new import_decimal.default(payment.service_fee || 0));
695
+ const rounding = new import_decimal.default(payment.rounding_amount || 0);
696
+ return amount.minus(rounding);
697
+ }
693
698
  calculatePaymentTotal(payments) {
694
699
  return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
695
700
  includeVoided: false
696
701
  }).reduce((sum, payment) => {
697
- const amount = new import_decimal.default(payment.amount || 0).minus(new import_decimal.default(payment.service_fee || 0));
698
- const rounding = new import_decimal.default(payment.rounding_amount || 0);
699
- return sum.plus(amount.minus(rounding));
702
+ return sum.plus(this.calculatePaymentEffectiveAmount(payment));
700
703
  }, new import_decimal.default(0));
701
704
  }
702
705
  normalizePaymentSource(payment, options) {
@@ -739,12 +742,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
739
742
  return {
740
743
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
741
744
  orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
745
+ gapPaidAmount: summary.gapPaidAmount.plus(this.calculatePaymentEffectiveAmount(paymentRecord)),
742
746
  payServiceChargeAmount: summary.payServiceChargeAmount.plus(this.calculatePaymentServiceFee(paymentRecord))
743
747
  };
744
748
  },
745
749
  {
746
750
  customerPaidAmount: new import_decimal.default(0),
747
751
  orderPaidAmount: new import_decimal.default(0),
752
+ gapPaidAmount: new import_decimal.default(0),
748
753
  payServiceChargeAmount: new import_decimal.default(0)
749
754
  }
750
755
  );
@@ -1078,7 +1083,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1078
1083
  amount_gap: this.calculateSummaryAmountGap({
1079
1084
  tempOrder,
1080
1085
  summary: (0, import_utils.createEmptySummary)(),
1081
- orderPaidAmount: paidPaymentSummary.orderPaidAmount
1086
+ orderPaidAmount: paidPaymentSummary.gapPaidAmount
1082
1087
  }),
1083
1088
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
1084
1089
  };
@@ -1100,7 +1105,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1100
1105
  amount_gap: this.calculateSummaryAmountGap({
1101
1106
  tempOrder,
1102
1107
  summary: salesSummaryResult,
1103
- orderPaidAmount: paidPaymentSummary.orderPaidAmount
1108
+ orderPaidAmount: paidPaymentSummary.gapPaidAmount
1104
1109
  }),
1105
1110
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
1106
1111
  };
@@ -1440,7 +1445,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1440
1445
  // ─── TempOrder: 商品 CRUD ───
1441
1446
  async addProductToOrder(product, booking) {
1442
1447
  var _a;
1443
- debugger;
1444
1448
  const tempOrder = this.ensureTempOrder();
1445
1449
  const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
1446
1450
  const productToAdd = (linked == null ? void 0 : linked.product) || product;
@@ -1836,7 +1840,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1836
1840
  * 应传 1,确保 /order/sales/checkout 返回打印所需数据。
1837
1841
  */
1838
1842
  async submitTempOrder(params) {
1839
- var _a, _b, _c;
1843
+ var _a, _b, _c, _d, _e;
1840
1844
  const tempOrder = this.ensureTempOrder();
1841
1845
  this.persistTempOrder();
1842
1846
  const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
@@ -1861,7 +1865,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1861
1865
  tempOrder,
1862
1866
  cacheId: effectiveCacheId,
1863
1867
  platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
1864
- businessCode: params == null ? void 0 : params.businessCode,
1868
+ businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1865
1869
  channel: params == null ? void 0 : params.channel,
1866
1870
  type: params == null ? void 0 : params.type,
1867
1871
  enhance: enhancePayload
@@ -1875,7 +1879,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1875
1879
  externalSaleNumber: payload.external_sale_number,
1876
1880
  requestUniqueIdempotencyToken: payload.request_unique_idempotency_token,
1877
1881
  paymentStatus: payload.payment_status,
1878
- paymentsCount: ((_b = payload.payments) == null ? void 0 : _b.length) || 0,
1882
+ paymentsCount: ((_d = payload.payments) == null ? void 0 : _d.length) || 0,
1879
1883
  smallTicketDataFlag: payload.small_ticket_data_flag
1880
1884
  });
1881
1885
  result = await this.submitSalesOrder({
@@ -1894,7 +1898,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1894
1898
  orderId: payload.order_id,
1895
1899
  externalSaleNumber: payload.external_sale_number,
1896
1900
  paymentStatus: payload.payment_status,
1897
- paymentsCount: ((_c = payload.payments) == null ? void 0 : _c.length) || 0
1901
+ paymentsCount: ((_e = payload.payments) == null ? void 0 : _e.length) || 0
1898
1902
  });
1899
1903
  throw error;
1900
1904
  }
@@ -1983,6 +1987,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1983
1987
  payments: mappedPayments,
1984
1988
  paymentStatus,
1985
1989
  smallTicketDataFlag: params.smallTicketDataFlag,
1990
+ businessCode: params.businessCode,
1986
1991
  channel: params.channel,
1987
1992
  enhancePayload: (payload) => {
1988
1993
  const nextPayload = {
@@ -439,6 +439,7 @@ export interface OrderPaymentMetadata {
439
439
  [key: string]: any;
440
440
  }
441
441
  export interface OrderPaymentData {
442
+ order_payment_id?: number | string;
442
443
  amount: string;
443
444
  code: string;
444
445
  custom_payment_id: number;
@@ -478,6 +479,7 @@ export interface SyncPaymentsToOrderParams {
478
479
  paymentStatus?: SubmitSalesOrderParams['query']['payment_status'];
479
480
  submitWhenPaid?: boolean;
480
481
  smallTicketDataFlag?: number;
482
+ businessCode?: string;
481
483
  channel?: string;
482
484
  }
483
485
  export interface SyncPaymentsToOrderResult<T = any> {
@@ -753,6 +753,7 @@ function mapPaymentItemToOrderPayment(paymentItem) {
753
753
  }
754
754
  }
755
755
  return {
756
+ ...item.order_payment_id !== void 0 ? { order_payment_id: item.order_payment_id } : {},
756
757
  amount: String(item.amount ?? "0.00"),
757
758
  code: String(item.code || ""),
758
759
  custom_payment_id: Number(customPaymentId ?? 0),
@@ -432,7 +432,6 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
432
432
  const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
433
433
  if (!params.forceRemote) {
434
434
  const localRecord = params.orderId !== void 0 ? await this.store.order.getLocalOrderByOrderId(params.orderId) : externalSaleNumber ? await this.store.order.getLocalOrderByExternalSaleNumber(externalSaleNumber) : params.orderNumber ? await this.store.order.getLocalOrderByOrderNumber(params.orderNumber) : null;
435
- debugger;
436
435
  if (localRecord) {
437
436
  const sales2 = await this.store.order.hydrateTempOrderFromRecord(localRecord, { recalcOnHydrate: false });
438
437
  this.currentSalesDetail = sales2;
@@ -1069,7 +1068,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1069
1068
  * payments 会交给 OrderModule 统一映射为 Sales 协议支付项。
1070
1069
  */
1071
1070
  async submitSalesOrder(params) {
1072
- var _a, _b, _c;
1071
+ var _a, _b, _c, _d;
1073
1072
  if (!this.store.order) {
1074
1073
  throw new Error("BaseSales 解决方案需要 order 模块支持");
1075
1074
  }
@@ -1078,9 +1077,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1078
1077
  const submitParams = {
1079
1078
  cacheId: this.cacheId,
1080
1079
  platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
1081
- businessCode: (_b = this.otherParams) == null ? void 0 : _b.businessCode,
1080
+ businessCode: ((_b = this.otherParams) == null ? void 0 : _b.businessCode) || ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1082
1081
  channel: this.getSubmitOrderSalesChannel(),
1083
- type: (_c = this.otherParams) == null ? void 0 : _c.type,
1082
+ type: (_d = this.otherParams) == null ? void 0 : _d.type,
1084
1083
  ...(params == null ? void 0 : params.payments) !== void 0 ? { payments: params.payments } : {},
1085
1084
  ...inferredPaymentStatus !== void 0 ? { paymentStatus: inferredPaymentStatus } : {},
1086
1085
  ...(params == null ? void 0 : params.smallTicketDataFlag) !== void 0 ? { smallTicketDataFlag: params.smallTicketDataFlag } : {},
@@ -1103,11 +1102,14 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1103
1102
  }
1104
1103
  }
1105
1104
  async syncPaymentsToOrder(params) {
1105
+ var _a, _b;
1106
1106
  if (!this.store.order)
1107
1107
  throw new Error("order 模块未初始化");
1108
+ const businessCode = params.businessCode ?? ((_a = this.otherParams) == null ? void 0 : _a.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.business_code);
1108
1109
  const channel = params.channel ?? this.getSubmitOrderSalesChannel();
1109
1110
  const syncParams = {
1110
1111
  ...params,
1112
+ ...businessCode !== void 0 ? { businessCode } : {},
1111
1113
  ...channel !== void 0 ? { channel } : {}
1112
1114
  };
1113
1115
  const syncState = this.store.order.getOrderSyncState();
@@ -1158,10 +1160,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1158
1160
  }
1159
1161
  /** 追加单个支付项到当前订单。 */
1160
1162
  addOrderPayment(payment) {
1163
+ var _a;
1161
1164
  if (!this.store.order)
1162
1165
  throw new Error("order 模块未初始化");
1163
1166
  const paymentRecord = payment;
1164
1167
  const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
1168
+ debugger;
1169
+ const shopWalletPassId = (_a = this.otherParams) == null ? void 0 : _a.shop_wallet_pass_id;
1170
+ if (shopWalletPassId !== void 0 && shopWalletPassId !== null) {
1171
+ metadata.shop_wallet_pass_id = shopWalletPassId;
1172
+ }
1165
1173
  if (!metadata.unique_identification_number) {
1166
1174
  metadata.unique_identification_number = (0, import_utils.createUuidV4)();
1167
1175
  }
@@ -22,6 +22,7 @@ __export(transformBaseProductToOrderProduct_exports, {
22
22
  transformBaseProductToOrderProduct: () => transformBaseProductToOrderProduct
23
23
  });
24
24
  module.exports = __toCommonJS(transformBaseProductToOrderProduct_exports);
25
+ var import_utils = require("../../../modules/Order/utils");
25
26
  var import_manualProductDiscount = require("../../../modules/Order/utils/manualProductDiscount");
26
27
  function toNumber(value, fallback = 0) {
27
28
  const parsedValue = Number(value);
@@ -158,6 +159,13 @@ function transformBaseProductToOrderProduct(params) {
158
159
  discount_per: (_k = payload._extend) == null ? void 0 : _k.discount_per
159
160
  })
160
161
  ) : payload.discount_list || [];
162
+ const optionSum = (0, import_utils.sumOptionUnitPrice)(productOptionItem).toNumber();
163
+ const mainProductOriginalPrice = toPriceString(Number(sourceProductPrice) + optionSum);
164
+ const bundleOnlyComposite = (0, import_utils.composeLinePrice)({ mainPrice: 0, bundle: productBundle });
165
+ const derivedMainSelling = Number(lineCompositeTotal) - Number(bundleOnlyComposite);
166
+ const mainProductSellingPrice = toPriceString(
167
+ Number.isFinite(derivedMainSelling) && derivedMainSelling >= 0 ? derivedMainSelling : Number(mainProductOriginalPrice)
168
+ );
161
169
  const metadata = {
162
170
  unique: payload.unique,
163
171
  session: payload.session,
@@ -170,8 +178,9 @@ function transformBaseProductToOrderProduct(params) {
170
178
  source_shop_id: payload.source_shop_id,
171
179
  origin,
172
180
  source_product_price: sourceProductPrice,
173
- main_product_selling_price: sourceProductPrice,
174
- main_product_original_price: sourceProductPrice,
181
+ main_product_selling_price: mainProductSellingPrice,
182
+ main_product_original_price: mainProductOriginalPrice,
183
+ price_schema_version: 2,
175
184
  ...hasPriceOverride ? {
176
185
  price_override: String(payload.price_override),
177
186
  is_manual_discount: 1
@@ -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 | 1 | 2 | 3 | 5 | 4 | 6;
314
+ weekNum: 0 | 5 | 1 | 4 | 2 | 3 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -7,6 +7,7 @@ import { BaseSalesImpl } from '../BaseSales';
7
7
  import type { BaseSalesScanCodeResult } from '../BaseSales/types';
8
8
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
9
9
  import type { LoadSalesDetailParams } from '../../modules/Order/types';
10
+ import type { GlobalScanHandleResult, GlobalScanHostBridge } from './types';
10
11
  import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
11
12
  import { type BuildCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildCacheItemFromOrderLine';
12
13
  import { type BuildNormalProductCacheItemFromOrderLineInput } from '../../modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine';
@@ -278,7 +279,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
278
279
  * 获取当前的客户搜索条件
279
280
  * @returns 当前搜索条件
280
281
  */
281
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
282
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
282
283
  /**
283
284
  * 获取客户列表状态(包含滚动加载相关状态)
284
285
  * @returns 客户状态
@@ -441,6 +442,20 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
441
442
  buildNormalProductCacheItemFromOrderLine(input: BuildNormalProductCacheItemFromOrderLineInput): Record<string, any>;
442
443
  /** 文档别名:与 OrderModule.updateOrderProduct 一致。 */
443
444
  updateProductInOrder(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
445
+ /**
446
+ * 全局扫码 pubsub 入口:解析码值 → 搜索 → 业务分发(客户 / 加车 / 开单)。
447
+ * UI 层在 pubsub 订阅回调里注入 `bridge`(uiHosts / action / cart.confirm*)。
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * await bookingTicket.handleGlobalScanCode(payload.data, {
452
+ * openProductDetail: uiHosts.openProductDetail,
453
+ * confirmDetail: cart.confirmDetail,
454
+ * openOrder: ({ order_id }) => action({ type: 'pisell1.handleOpenCachedBigSale', data: { order_id } }),
455
+ * });
456
+ * ```
457
+ */
458
+ handleGlobalScanCode(code: string, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;
444
459
  /**
445
460
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
446
461
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -41,6 +41,8 @@ var import_scan = __toESM(require("./utils/scan"));
41
41
  var import_orderCustomer = require("./utils/orderCustomer");
42
42
  var import_handleScan = require("./utils/scan/handleScan");
43
43
  var import_scanCache = __toESM(require("./utils/scan/scanCache"));
44
+ var import_formatGlobalScan = require("./utils/scan/formatGlobalScan");
45
+ var import_applyGlobalScan = require("./utils/scan/applyGlobalScan");
44
46
  var import_cartView = require("./utils/cartView");
45
47
  var import_addProductDecision = require("./utils/addProductDecision");
46
48
  var import_buildCacheItemFromOrderLine = require("../../modules/BookingContext/utils/buildCacheItemFromOrderLine");
@@ -1017,6 +1019,60 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1017
1019
  async updateProductInOrder(params) {
1018
1020
  return this.updateOrderProduct(params);
1019
1021
  }
1022
+ /**
1023
+ * 全局扫码 pubsub 入口:解析码值 → 搜索 → 业务分发(客户 / 加车 / 开单)。
1024
+ * UI 层在 pubsub 订阅回调里注入 `bridge`(uiHosts / action / cart.confirm*)。
1025
+ *
1026
+ * @example
1027
+ * ```ts
1028
+ * await bookingTicket.handleGlobalScanCode(payload.data, {
1029
+ * openProductDetail: uiHosts.openProductDetail,
1030
+ * confirmDetail: cart.confirmDetail,
1031
+ * openOrder: ({ order_id }) => action({ type: 'pisell1.handleOpenCachedBigSale', data: { order_id } }),
1032
+ * });
1033
+ * ```
1034
+ */
1035
+ async handleGlobalScanCode(code, bridge) {
1036
+ var _a, _b, _c, _d;
1037
+ const trimmed = typeof code === "string" ? code.trim() : "";
1038
+ if (!trimmed) {
1039
+ (_a = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _a.call(bridge, "fail", "pisell2.text.scan-global-failed");
1040
+ return { status: "failed", reason: "empty_code" };
1041
+ }
1042
+ try {
1043
+ const localSearch = (v) => this.store.products.findProductsByCodeOrBarcode(v);
1044
+ const scanCallback = (0, import_handleScan.handleGlobalScan)(this.request, localSearch);
1045
+ const raw = await scanCallback({ type: "nativeScanner", value: trimmed });
1046
+ const formatted = (0, import_formatGlobalScan.formatGlobalScanResult)(raw, trimmed);
1047
+ if (!formatted) {
1048
+ (_b = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _b.call(bridge, "fail", "pisell2.text.scan-global-failed");
1049
+ return { status: "failed", reason: "not_found" };
1050
+ }
1051
+ const result = await (0, import_applyGlobalScan.applyGlobalScan)(
1052
+ {
1053
+ setOrderCustomer: (customer) => this.setOrderCustomer(customer),
1054
+ getOrderCustomerSnapshot: () => this.getOrderCustomerSnapshot(),
1055
+ getBusinessCode: () => {
1056
+ var _a2;
1057
+ return (_a2 = this.otherParams) == null ? void 0 : _a2.businessCode;
1058
+ },
1059
+ buildAddProductCtx: (extra) => this.buildAddProductCtx(extra),
1060
+ decideAddProduct: (item, options) => this.decideAddProduct(item, options),
1061
+ decideAfterDetail: (cacheItem, options) => this.decideAfterDetail(cacheItem, options),
1062
+ transformDetailToProductAndBooking: (input) => this.transformDetailToProductAndBooking(input),
1063
+ addProductToOrder: (product, booking) => this.addProductToOrder(product, booking)
1064
+ },
1065
+ formatted,
1066
+ bridge
1067
+ );
1068
+ (_c = bridge == null ? void 0 : bridge.refresh) == null ? void 0 : _c.call(bridge);
1069
+ return result;
1070
+ } catch (error) {
1071
+ console.error("[BookingTicket] handleGlobalScanCode failed", error);
1072
+ (_d = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _d.call(bridge, "fail", "pisell2.text.scan-global-failed");
1073
+ return { status: "failed", reason: "not_found" };
1074
+ }
1075
+ }
1020
1076
  /**
1021
1077
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
1022
1078
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -134,3 +134,51 @@ export interface BookingTicketCustomerView {
134
134
  export interface BookingTicketProductCatalogView {
135
135
  products: ProductData[];
136
136
  }
137
+ /** 扫码宿主桥接:SalesSdk 在 pubsub 订阅回调里注入,OS 需要 UI 时直接调用 */
138
+ export interface GlobalScanHostBridge {
139
+ openProductDetail?: (payload: Record<string, any>) => Promise<any | null>;
140
+ openBookingEdit?: (payload: Record<string, any>) => Promise<any | null>;
141
+ confirmDetail?: (input: {
142
+ item: any;
143
+ detailResult: {
144
+ e: any;
145
+ extension_type?: any;
146
+ detail?: any;
147
+ };
148
+ options?: Record<string, any>;
149
+ }) => Promise<any>;
150
+ confirmBookingEdit?: (input: {
151
+ cacheItem: any;
152
+ options?: Record<string, any>;
153
+ }) => Promise<any>;
154
+ openOrder?: (data: {
155
+ order_id: number;
156
+ business_code?: string;
157
+ }) => void;
158
+ /**
159
+ * walk-in 扫 walletPass:直接核销优惠码(对齐 SaleDetail Voucher.handleApplyCode / cart.scanCode)。
160
+ */
161
+ applyPromotionCode?: (code: string, customerId?: number) => Promise<{
162
+ isAvailable?: boolean;
163
+ type?: string;
164
+ unavailableReason?: string;
165
+ }>;
166
+ onNotify?: (type: 'success' | 'fail' | 'info', messageKey?: string) => void;
167
+ refresh?: () => void;
168
+ }
169
+ /** handleGlobalScanCode 结构化返回 */
170
+ export type GlobalScanHandleResult = {
171
+ status: 'success';
172
+ kind: 'customer' | 'products' | 'promotion';
173
+ meta?: {
174
+ count?: number;
175
+ };
176
+ } | {
177
+ status: 'pending';
178
+ kind: 'openOrder' | 'requiresDetail' | 'requiresBookingEdit';
179
+ } | {
180
+ status: 'cancelled';
181
+ } | {
182
+ status: 'failed';
183
+ reason: 'empty_code' | 'not_found' | 'invalid_data' | 'no_bridge';
184
+ };
@@ -0,0 +1,36 @@
1
+ import type { GlobalScanHandleResult, GlobalScanHostBridge, ICustomer } from '../../types';
2
+ import type { AddProductDecision } from '../addProductDecision';
3
+ import { GlobalScanFormattedResult } from './formatGlobalScan';
4
+ /** applyGlobalScan 所需的 BookingTicket 运行时能力 */
5
+ export interface GlobalScanApplyHost {
6
+ setOrderCustomer(customer: ICustomer | null): void;
7
+ getOrderCustomerSnapshot(): ICustomer | null;
8
+ getBusinessCode(): string | undefined;
9
+ buildAddProductCtx(extra?: Record<string, any>): Record<string, any>;
10
+ decideAddProduct(item: any, options?: Record<string, any>): AddProductDecision;
11
+ decideAfterDetail(cacheItem: any, options?: Record<string, any>): AddProductDecision;
12
+ transformDetailToProductAndBooking(input: {
13
+ item: any;
14
+ cacheItem?: any;
15
+ detailResult?: {
16
+ e: any;
17
+ extension_type?: any;
18
+ detail?: any;
19
+ };
20
+ options?: Record<string, any>;
21
+ }): {
22
+ product: any;
23
+ booking?: any;
24
+ cacheItem: any;
25
+ };
26
+ addProductToOrder(product: any, booking?: any): Promise<any>;
27
+ }
28
+ /**
29
+ * 应用全局扫码格式化结果:设客户 / 加车 / 开单 / 弹窗链。
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const result = await applyGlobalScan(bookingTicket, formatted, bridge);
34
+ * ```
35
+ */
36
+ export declare function applyGlobalScan(host: GlobalScanApplyHost, formatted: GlobalScanFormattedResult, bridge?: GlobalScanHostBridge): Promise<GlobalScanHandleResult>;