@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
@@ -200,7 +200,7 @@ export function buildRequiresDetailPayload(item, ctx) {
200
200
  number: Boolean(item === null || item === void 0 ? void 0 : item.open_sold_weight)
201
201
  },
202
202
  isOnlySession: isOnlySession,
203
- isEject: isEject,
203
+ isEject: isEject ? 1 : 0,
204
204
  customerId: ctx === null || ctx === void 0 ? void 0 : ctx.customerId,
205
205
  date: formatBookingDateForUI(ctx === null || ctx === void 0 ? void 0 : ctx.date),
206
206
  productData: item
@@ -339,6 +339,8 @@ function buildBasePayloadFromCacheItem(cacheItem, ctx) {
339
339
  origin_total: extend === null || extend === void 0 ? void 0 : extend.origin_total,
340
340
  price_override: extend === null || extend === void 0 ? void 0 : extend.priceOverride,
341
341
  bundle_edit: extend === null || extend === void 0 ? void 0 : extend.bundle_edit,
342
+ discount_reason: extend === null || extend === void 0 ? void 0 : extend.discount_reason,
343
+ discount_list: cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.discount_list,
342
344
  _extend: extend
343
345
  };
344
346
  }
@@ -14,6 +14,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
14
14
  import dayjs from 'dayjs';
15
15
  import Decimal from 'decimal.js';
16
16
  import { composeLinePrice, createUuidV4, resolveManualOverrideLineOriginalPrice, sumOptionUnitPrice } from "../../modules/Order/utils";
17
+ import { ensureManualProductDiscountList } from "../../modules/Order/utils/manualProductDiscount";
17
18
 
18
19
  /**
19
20
  * 构建金额全为 0 的空 summary。
@@ -605,8 +606,16 @@ export function normalizeOrderProduct(product) {
605
606
  });
606
607
  var finalOriginalPrice = resolveManualOverrideLineOriginalPrice({
607
608
  num: product.num,
608
- metadata: metadata
609
+ metadata: metadata,
610
+ lineOriginalPrice: product.original_price
609
611
  }, composedOriginalPrice);
612
+ var discountList = ensureManualProductDiscountList({
613
+ discountList: product.discount_list,
614
+ metadata: metadata,
615
+ originalPrice: finalOriginalPrice,
616
+ sellingPrice: composedSellingPrice,
617
+ quantity: getSafeProductNum(product.num)
618
+ });
610
619
  return {
611
620
  order_detail_id: product.order_detail_id || null,
612
621
  product_id: product.product_id,
@@ -617,7 +626,7 @@ export function normalizeOrderProduct(product) {
617
626
  original_price: finalOriginalPrice,
618
627
  tax_fee: product.tax_fee || '0.00',
619
628
  is_charge_tax: (_product$is_charge_ta = product.is_charge_tax) !== null && _product$is_charge_ta !== void 0 ? _product$is_charge_ta : 0,
620
- discount_list: product.discount_list || [],
629
+ discount_list: discountList,
621
630
  product_bundle: normalizedBundle,
622
631
  metadata: metadata,
623
632
  note: product.note != null ? String(product.note) : ''
@@ -150,12 +150,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
150
150
  customerId: number;
151
151
  }): Promise<void>;
152
152
  private recalculateOrderPricesFromQuotation;
153
- scanCode(code: string, customerId?: number): Promise<{
154
- isAvailable: boolean;
155
- discountList: import("../../modules/Discount").Discount[];
156
- type: "server" | "clientCalc";
157
- unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
158
- }>;
153
+ scanCode(code: string, customerId?: number): Promise<import("../../modules/Order/types").OrderScanCodeResult>;
159
154
  /** 获取当前折扣列表(包装 order.getDiscountList) */
160
155
  getDiscountList(): import("../../modules/Discount").Discount[];
161
156
  /** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
@@ -1,49 +0,0 @@
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
- });
@@ -33,6 +33,7 @@ __export(buildCacheItemFromOrderLine_exports, {
33
33
  });
34
34
  module.exports = __toCommonJS(buildCacheItemFromOrderLine_exports);
35
35
  var import_dayjs = __toESM(require("dayjs"));
36
+ var import_manualProductDiscount = require("../../Order/utils/manualProductDiscount");
36
37
  function safeFormat(value, fmt) {
37
38
  if (value === void 0 || value === null)
38
39
  return void 0;
@@ -79,10 +80,28 @@ function unflattenResourceMap(resources) {
79
80
  });
80
81
  return map;
81
82
  }
82
- function buildCapacityFromBooking(resources) {
83
- if (!Array.isArray(resources))
84
- return [];
85
- return resources.filter((r) => (r == null ? void 0 : r.relation_id) !== void 0 && (r == null ? void 0 : r.relation_id) !== null && r.capacity !== void 0).map((r) => ({ id: r.relation_id, value: Number(r.capacity || 0) }));
83
+ function resolveCapacityFromBooking(booking) {
84
+ var _a;
85
+ const metaCap = (_a = booking.metadata) == null ? void 0 : _a.capacity;
86
+ if (Array.isArray(metaCap) && metaCap.length > 0) {
87
+ return metaCap.map((item) => {
88
+ if (!item || typeof item !== "object")
89
+ return null;
90
+ if (item.id === void 0 || item.id === null)
91
+ return null;
92
+ const row = {
93
+ id: item.id,
94
+ value: Number(item.value ?? 0)
95
+ };
96
+ if (item.name !== void 0)
97
+ row.name = item.name;
98
+ return row;
99
+ }).filter((item) => item != null);
100
+ }
101
+ if (typeof metaCap === "number" && Number.isFinite(metaCap)) {
102
+ return [{ id: 0, value: metaCap, name: "" }];
103
+ }
104
+ return [];
86
105
  }
87
106
  function resolveDurationForExtend(booking) {
88
107
  const duration = booking.duration;
@@ -95,7 +114,7 @@ function resolveDurationForExtend(booking) {
95
114
  return duration;
96
115
  }
97
116
  function buildCacheItemFromOrderLine(input) {
98
- var _a, _b, _c, _d, _e, _f;
117
+ var _a, _b, _c, _d, _e, _f, _g, _h;
99
118
  const { product, booking, sourceProduct } = input;
100
119
  const resolvedId = product.product_id ?? (sourceProduct == null ? void 0 : sourceProduct.id);
101
120
  const selling = Number(product.selling_price ?? 0);
@@ -105,7 +124,7 @@ function buildCacheItemFromOrderLine(input) {
105
124
  const startTime = normalizeTimeString(booking.start_time);
106
125
  const endTime = normalizeTimeString(booking.end_time);
107
126
  const resource = unflattenResourceMap(booking.resources);
108
- const capacity = buildCapacityFromBooking(booking.resources);
127
+ const capacity = resolveCapacityFromBooking(booking);
109
128
  const holderId = ((_a = booking.metadata) == null ? void 0 : _a.holder_id) ?? booking.holder_id;
110
129
  const other = {
111
130
  product_variant_id: product.product_variant_id ?? 0,
@@ -131,8 +150,22 @@ function buildCacheItemFromOrderLine(input) {
131
150
  capacity,
132
151
  holder_id: holderId,
133
152
  other,
134
- like_status: booking.like_status || "common"
153
+ like_status: booking.like_status || "common",
154
+ discount_reason: (0, import_manualProductDiscount.resolveManualDiscountMessage)(
155
+ product.discount_list,
156
+ (_e = product.metadata) == null ? void 0 : _e.product_discount_reason
157
+ ) || void 0
135
158
  };
159
+ const manualDiscount = (product.discount_list || []).find((d) => (d == null ? void 0 : d.type) === "product");
160
+ if (manualDiscount && extend.origin_total === selling) {
161
+ const manualAmount = Number(manualDiscount.amount ?? 0);
162
+ if (Number.isFinite(manualAmount) && manualAmount > 0) {
163
+ extend.origin_total = selling + manualAmount;
164
+ }
165
+ }
166
+ if (((_f = product.metadata) == null ? void 0 : _f.price_override) != null || manualDiscount) {
167
+ extend.priceOverride = selling;
168
+ }
136
169
  if (booking.holder !== void 0) {
137
170
  extend.holder = booking.holder;
138
171
  }
@@ -143,8 +176,8 @@ function buildCacheItemFromOrderLine(input) {
143
176
  ...sourceProduct || {},
144
177
  id: resolvedId,
145
178
  product_id: resolvedId,
146
- extension_type: (sourceProduct == null ? void 0 : sourceProduct.extension_type) ?? ((_e = booking == null ? void 0 : booking.product) == null ? void 0 : _e.extension_type) ?? (sourceProduct == null ? void 0 : sourceProduct.extension_type),
147
- title: (sourceProduct == null ? void 0 : sourceProduct.title) ?? ((_f = booking == null ? void 0 : booking.product) == null ? void 0 : _f.title),
179
+ extension_type: (sourceProduct == null ? void 0 : sourceProduct.extension_type) ?? ((_g = booking == null ? void 0 : booking.product) == null ? void 0 : _g.extension_type) ?? (sourceProduct == null ? void 0 : sourceProduct.extension_type),
180
+ title: (sourceProduct == null ? void 0 : sourceProduct.title) ?? ((_h = booking == null ? void 0 : booking.product) == null ? void 0 : _h.title),
148
181
  price: (sourceProduct == null ? void 0 : sourceProduct.price) ?? selling,
149
182
  selling_price: product.selling_price,
150
183
  original_price: product.original_price,
@@ -50,11 +50,21 @@ export interface BookingResourceInput {
50
50
  metadata?: Record<string, any>;
51
51
  children?: any[];
52
52
  }
53
+ /** custom / package 人数维度快照,与 info2 `_extend.capacity` / `metadata.capacity` 对齐。 */
54
+ export interface BookingCapacityMetadataItem {
55
+ id: string | number;
56
+ value: number;
57
+ name?: Record<string, any> | string;
58
+ }
53
59
  export interface BookingMetadataInput {
54
60
  /** 由 OS createLinkedProductAndBooking 统一改写,这里不生成。 */
55
61
  unique_identification_number?: string;
56
62
  collect_pax?: number;
57
- capacity?: number;
63
+ /**
64
+ * 资源容量快照:custom 多维度时为 `{ id, value, name? }[]`;
65
+ * 仅总和场景可为 number(capacity_snapshot 兼容)。
66
+ */
67
+ capacity?: number | BookingCapacityMetadataItem[];
58
68
  /** 协议要求始终提交(即使为 null)。 */
59
69
  holder_id: any;
60
70
  resource_select_type?: 'single' | 'multiple' | string;
@@ -36,6 +36,24 @@ var import_dayjs = __toESM(require("dayjs"));
36
36
  var import_serviceTimes = require("./serviceTimes");
37
37
  var import_resources = require("./resources");
38
38
  var import_flexible = require("./flexible");
39
+ function normalizeExtendCapacityForMetadata(capacity) {
40
+ if (!Array.isArray(capacity) || capacity.length === 0)
41
+ return void 0;
42
+ const normalized = capacity.map((item) => {
43
+ if (!item || typeof item !== "object")
44
+ return null;
45
+ if (item.id === void 0 || item.id === null)
46
+ return null;
47
+ const row = {
48
+ id: item.id,
49
+ value: Number(item.value ?? 0)
50
+ };
51
+ if (item.name !== void 0)
52
+ row.name = item.name;
53
+ return row;
54
+ }).filter((item) => item != null);
55
+ return normalized.length > 0 ? normalized : void 0;
56
+ }
39
57
  function safeFormat(value, fmt) {
40
58
  if (value === void 0 || value === null)
41
59
  return void 0;
@@ -158,7 +176,10 @@ function cacheItemToBookingInput(cacheItem, options) {
158
176
  }
159
177
  if (ext.collect_pax !== void 0)
160
178
  metadata.collect_pax = ext.collect_pax;
161
- if (ext.capacity_snapshot !== void 0) {
179
+ const extendCapacity = normalizeExtendCapacityForMetadata(ext.capacity);
180
+ if (extendCapacity) {
181
+ metadata.capacity = extendCapacity;
182
+ } else if (ext.capacity_snapshot !== void 0) {
162
183
  metadata.capacity = ext.capacity_snapshot;
163
184
  }
164
185
  const selectType = deriveResourceSelectType(cacheItem) || ((_b = options == null ? void 0 : options.bookingConfig) == null ? void 0 : _b.resource_select_type);
@@ -24,6 +24,12 @@ export declare class CustomerModule extends BaseModule implements Module, Custom
24
24
  * @param operation 操作名称
25
25
  */
26
26
  private handleCustomerListError;
27
+ /**
28
+ * 查询客户列表但不写入 customerList / pagination 状态。
29
+ *
30
+ * 用于按 ID 补齐客户等内部查询,避免把临时的 num/searchParams 污染到滚动列表。
31
+ */
32
+ queryCustomerList(params?: ShopGetCustomerListParams): Promise<ICustomerListResponse>;
27
33
  /**
28
34
  * 获取客户列表
29
35
  * @param params 查询参数
@@ -75,7 +75,7 @@ var CustomerModule = class extends import_BaseModule.BaseModule {
75
75
  } else {
76
76
  this.store.currentPage = 1;
77
77
  }
78
- if (typeof ((_e = options == null ? void 0 : options.initialState) == null ? void 0 : _e.pageSize) === "number") {
78
+ if (typeof ((_e = options == null ? void 0 : options.initialState) == null ? void 0 : _e.pageSize) === "number" && options.initialState.pageSize > 1) {
79
79
  this.store.pageSize = options.initialState.pageSize;
80
80
  } else {
81
81
  this.store.pageSize = import_constants.DEFAULT_PAGE_SIZE;
@@ -152,6 +152,20 @@ var CustomerModule = class extends import_BaseModule.BaseModule {
152
152
  this.store.error
153
153
  );
154
154
  }
155
+ /**
156
+ * 查询客户列表但不写入 customerList / pagination 状态。
157
+ *
158
+ * 用于按 ID 补齐客户等内部查询,避免把临时的 num/searchParams 污染到滚动列表。
159
+ */
160
+ async queryCustomerList(params = {}) {
161
+ const { customerList, total, page, pageSize } = await this.fetchCustomerListData(params);
162
+ return {
163
+ list: customerList,
164
+ total,
165
+ page,
166
+ pageSize
167
+ };
168
+ }
155
169
  /**
156
170
  * 获取客户列表
157
171
  * @param params 查询参数
@@ -352,12 +366,13 @@ var CustomerModule = class extends import_BaseModule.BaseModule {
352
366
  try {
353
367
  this.store.loadingMore = true;
354
368
  this.store.error = null;
355
- const { customerList: newCustomers, total, page, pageSize } = await this.fetchCustomerListData({
369
+ const loadMoreParams = {
356
370
  skip: nextPage,
357
371
  num: this.store.pageSize,
358
372
  ...this.store.searchParams
359
373
  // 使用存储的搜索条件
360
- });
374
+ };
375
+ const { customerList: newCustomers, total, page, pageSize } = await this.fetchCustomerListData(loadMoreParams);
361
376
  const updatedCustomerList = [...this.store.customerList, ...(0, import_lodash_es.cloneDeep)(newCustomers)];
362
377
  this.store.customerList = updatedCustomerList;
363
378
  this.store.currentPage = page;
@@ -110,6 +110,8 @@ export interface CustomerState {
110
110
  export interface CustomerModuleAPI {
111
111
  /** 获取客户列表 */
112
112
  getCustomerList: (params?: ShopGetCustomerListParams) => Promise<ICustomerListResponse>;
113
+ /** 查询客户列表但不更新列表分页状态 */
114
+ queryCustomerList: (params?: ShopGetCustomerListParams) => Promise<ICustomerListResponse>;
113
115
  /** 设置客户列表 */
114
116
  setCustomerList: (customers: ShopCustomer[], total?: number) => void;
115
117
  /** 设置当前选择的客户 */
@@ -135,6 +135,7 @@ export interface Discount {
135
135
  appliedProductDetails: ApplicableProductDetails[];
136
136
  isDisabledForProductUsed?: boolean;
137
137
  amount?: number;
138
+ customer_id?: number | string | null;
138
139
  extension_data?: ExtensionData[];
139
140
  total_order_behavior_count?: number;
140
141
  today_order_behavior_count?: number;
@@ -3,10 +3,9 @@ import { BaseModule } from '../BaseModule';
3
3
  import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
5
  import { type SubmitPayloadEnhancer } from './utils';
6
- import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions } from './types';
6
+ import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, OrderScanCodeResult, ReplaceTempOrderOptions } from './types';
7
7
  import type { ICustomer } from '../AccountList/types';
8
8
  import type { Discount } from '../Discount/types';
9
- import { UnavailableReason } from '../Rules/types';
10
9
  export declare class OrderModule extends BaseModule implements Module, OrderModuleAPI {
11
10
  protected defaultName: string;
12
11
  protected defaultVersion: string;
@@ -48,12 +47,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
48
47
  apply?: boolean;
49
48
  }): Promise<Discount[]>;
50
49
  getDiscountList(): Discount[];
51
- scanCode(code: string, customerId?: number): Promise<{
52
- isAvailable: boolean;
53
- discountList: Discount[];
54
- type: 'server' | 'clientCalc';
55
- unavailableReason?: UnavailableReason;
56
- }>;
50
+ scanCode(code: string, customerId?: number): Promise<OrderScanCodeResult>;
57
51
  applyDiscount(): void;
58
52
  initTempOrder(params: {
59
53
  cacheId?: string;
@@ -109,10 +103,11 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
109
103
  updateTempOrderShopDiscount(amount: string | number): string;
110
104
  updateTempOrderBuzzer(buzzer: string): string;
111
105
  updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
106
+ private buildTempOrderCustomer;
112
107
  /**
113
108
  * 更新当前 tempOrder 的客户协议字段。
114
109
  *
115
- * PaymentModal 只需要修改订单里的客户字段;如果外部还有客户模块需要同步,
110
+ * PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
116
111
  * 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
117
112
  */
118
113
  updateTempOrderCustomer(customer: UpdateTempOrderCustomerInput): OrderSnapshot['customer'];
@@ -190,7 +185,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
190
185
  private logSubmitBackendRejected;
191
186
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
192
187
  createOrder(params: CommitOrderParams['query']): {
193
- type: "virtual" | "appointment_booking";
188
+ type: "appointment_booking" | "virtual";
194
189
  platform: string;
195
190
  sales_channel: string;
196
191
  order_sales_channel: string;
@@ -38,6 +38,7 @@ var import_utils = require("./utils");
38
38
  var import_utils2 = require("../Product/utils");
39
39
  var import_dayjs = __toESM(require("dayjs"));
40
40
  var import_utils3 = require("../../solution/ScanOrder/utils");
41
+ var import_manualProductDiscount = require("./utils/manualProductDiscount");
41
42
  var import_Discount = require("../Discount");
42
43
  var import_Rules = require("../Rules");
43
44
  var import_types2 = require("../Rules/types");
@@ -207,6 +208,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
207
208
  type: "clientCalc",
208
209
  isAvailable: false,
209
210
  discountList: this.getDiscountList(),
211
+ scannedDiscountList: resultDiscountList,
210
212
  unavailableReason: import_types2.UnavailableReason.Unknown
211
213
  };
212
214
  }
@@ -214,7 +216,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
214
216
  return {
215
217
  type: "server",
216
218
  isAvailable: false,
217
- discountList: this.getDiscountList()
219
+ discountList: this.getDiscountList(),
220
+ scannedDiscountList: resultDiscountList
218
221
  };
219
222
  }
220
223
  const withScanList = resultDiscountList.map((item) => ({
@@ -226,7 +229,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
226
229
  return {
227
230
  type: "clientCalc",
228
231
  isAvailable: true,
229
- discountList: this.getDiscountList()
232
+ discountList: this.getDiscountList(),
233
+ scannedDiscountList: resultDiscountList
230
234
  };
231
235
  }
232
236
  const tempOrder = this.store.tempOrder;
@@ -247,6 +251,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
247
251
  type: "clientCalc",
248
252
  isAvailable: isAvailable || false,
249
253
  discountList: newDiscountList || this.getDiscountList(),
254
+ scannedDiscountList: resultDiscountList,
250
255
  unavailableReason
251
256
  };
252
257
  }
@@ -268,7 +273,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
268
273
  orderTotalAmount: Number(((_d = this.store.summary) == null ? void 0 : _d.total_amount) || 0)
269
274
  });
270
275
  if (result == null ? void 0 : result.productList) {
271
- tempOrder.products = result.productList;
276
+ tempOrder.products = (result.productList || []).map((product) => ({
277
+ ...product,
278
+ discount_list: (0, import_manualProductDiscount.syncManualProductDiscountProductNum)(
279
+ product.discount_list,
280
+ product.num
281
+ )
282
+ }));
272
283
  }
273
284
  if (result == null ? void 0 : result.discountList) {
274
285
  OrderModule.populateSavedAmounts(
@@ -874,10 +885,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
874
885
  this.persistTempOrder();
875
886
  return tempOrder.contacts_info;
876
887
  }
888
+ buildTempOrderCustomer(params) {
889
+ if (!params.customerId)
890
+ return null;
891
+ const source = params.source ? (0, import_lodash_es.cloneDeep)(params.source) : {};
892
+ const name = source.name ?? source.display_name ?? source.customerName ?? source.customer_name ?? params.customerName;
893
+ const customerName = source.customer_name ?? source.customerName ?? source.display_name ?? source.name ?? params.customerName;
894
+ return {
895
+ ...source,
896
+ id: source.id ?? params.customerId,
897
+ customer_id: source.customer_id ?? params.customerId,
898
+ name: String(name || ""),
899
+ customer_name: String(customerName || ""),
900
+ country_calling_code: String(
901
+ source.country_calling_code ?? source.countryCallingCode ?? params.countryCallingCode
902
+ ),
903
+ phone: String(source.phone ?? params.phone),
904
+ email: String(source.email ?? params.email)
905
+ };
906
+ }
877
907
  /**
878
908
  * 更新当前 tempOrder 的客户协议字段。
879
909
  *
880
- * PaymentModal 只需要修改订单里的客户字段;如果外部还有客户模块需要同步,
910
+ * PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
881
911
  * 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
882
912
  */
883
913
  updateTempOrderCustomer(customer) {
@@ -891,6 +921,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
891
921
  );
892
922
  tempOrder.phone = String(customer.phone || "");
893
923
  tempOrder.email = String(customer.email || "");
924
+ tempOrder.customer = this.buildTempOrderCustomer({
925
+ source: customer,
926
+ customerId: tempOrder.customer_id,
927
+ customerName: tempOrder.customer_name,
928
+ countryCallingCode: tempOrder.country_calling_code,
929
+ phone: tempOrder.phone,
930
+ email: tempOrder.email
931
+ });
894
932
  this.persistTempOrder();
895
933
  return {
896
934
  customerId: tempOrder.customer_id,
@@ -910,6 +948,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
910
948
  tempOrder.country_calling_code = String(patch.country_calling_code || "");
911
949
  tempOrder.phone = String(patch.phone || "");
912
950
  tempOrder.email = String(patch.email || "");
951
+ tempOrder.customer = this.buildTempOrderCustomer({
952
+ source: snapshot || null,
953
+ customerId: tempOrder.customer_id,
954
+ customerName: tempOrder.customer_name,
955
+ countryCallingCode: tempOrder.country_calling_code,
956
+ phone: tempOrder.phone,
957
+ email: tempOrder.email
958
+ });
913
959
  if (snapshot !== void 0) {
914
960
  const extend = this.ensureExtend(tempOrder);
915
961
  if (snapshot === null)
@@ -941,11 +987,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
941
987
  }
942
988
  clearOrderCustomer() {
943
989
  const tempOrder = this.ensureTempOrder();
944
- tempOrder.customer_id = 0;
990
+ tempOrder.customer_id = null;
945
991
  tempOrder.customer_name = "";
946
992
  tempOrder.country_calling_code = "";
947
993
  tempOrder.phone = "";
948
994
  tempOrder.email = "";
995
+ tempOrder.customer = null;
949
996
  if (tempOrder._extend)
950
997
  delete tempOrder._extend.customerSnapshot;
951
998
  this.persistTempOrder();
@@ -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;