@pisell/pisellos 2.2.164 → 2.2.166

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/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +45 -15
  2. package/dist/modules/Order/index.d.ts +10 -3
  3. package/dist/modules/Order/index.js +275 -142
  4. package/dist/modules/Order/types.d.ts +9 -2
  5. package/dist/modules/Order/types.js +2 -0
  6. package/dist/modules/Order/utils.d.ts +13 -0
  7. package/dist/modules/Order/utils.js +69 -15
  8. package/dist/server/index.js +1 -0
  9. package/dist/solution/BaseSales/index.d.ts +9 -1
  10. package/dist/solution/BaseSales/index.js +378 -241
  11. package/dist/solution/BaseSales/types.d.ts +3 -0
  12. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +33 -14
  13. package/dist/solution/BaseSales/utils.js +36 -7
  14. package/dist/solution/BookingTicket/index.d.ts +3 -0
  15. package/dist/solution/BookingTicket/index.js +170 -86
  16. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +4 -2
  17. package/dist/solution/BookingTicket/utils/addProductDecision.js +37 -19
  18. package/dist/solution/ScanOrder/utils.js +36 -7
  19. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +35 -9
  20. package/lib/modules/Order/index.d.ts +10 -3
  21. package/lib/modules/Order/index.js +107 -4
  22. package/lib/modules/Order/types.d.ts +9 -2
  23. package/lib/modules/Order/utils.d.ts +13 -0
  24. package/lib/modules/Order/utils.js +57 -9
  25. package/lib/server/index.js +1 -0
  26. package/lib/solution/BaseSales/index.d.ts +9 -1
  27. package/lib/solution/BaseSales/index.js +71 -3
  28. package/lib/solution/BaseSales/types.d.ts +3 -0
  29. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +31 -10
  30. package/lib/solution/BaseSales/utils.js +37 -5
  31. package/lib/solution/BookingTicket/index.d.ts +3 -0
  32. package/lib/solution/BookingTicket/index.js +57 -6
  33. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +4 -2
  34. package/lib/solution/BookingTicket/utils/addProductDecision.js +28 -12
  35. package/lib/solution/ScanOrder/utils.js +37 -5
  36. package/package.json +1 -1
@@ -57,8 +57,23 @@ function resolveSourceProductPrice(product, sourceProduct) {
57
57
  }
58
58
  return Number(product.selling_price ?? 0);
59
59
  }
60
+ function mapOrderBundleToOtherBundle(bundle) {
61
+ return bundle.map((item) => {
62
+ const catalogOriginal = item.original_price ?? item.product_price ?? item.price ?? item.bundle_selling_price;
63
+ const selling = item.bundle_selling_price ?? item.price ?? catalogOriginal;
64
+ const { bundle_selling_price: _omitBundleSelling, ...rest } = item;
65
+ return {
66
+ ...rest,
67
+ price: selling,
68
+ original_price: catalogOriginal,
69
+ original_total: item.original_total ?? catalogOriginal,
70
+ num: item.num ?? item.quantity ?? 1,
71
+ quantity: item.quantity ?? item.num ?? 1
72
+ };
73
+ });
74
+ }
60
75
  function buildNormalProductCacheItemFromOrderLine(input) {
61
- var _a;
76
+ var _a, _b, _c, _d;
62
77
  const { product, sourceProduct } = input;
63
78
  const resolvedId = product.product_id ?? (sourceProduct == null ? void 0 : sourceProduct.id);
64
79
  const sourcePrice = resolveSourceProductPrice(product, sourceProduct);
@@ -66,33 +81,44 @@ function buildNormalProductCacheItemFromOrderLine(input) {
66
81
  const original = Number(product.original_price ?? selling);
67
82
  const uid = (_a = product.metadata) == null ? void 0 : _a.unique_identification_number;
68
83
  const option = Array.isArray(product.product_option_item) ? [...product.product_option_item] : [];
69
- const bundle = Array.isArray(product.product_bundle) ? [...product.product_bundle] : [];
84
+ const bundle = mapOrderBundleToOtherBundle(
85
+ Array.isArray(product.product_bundle) ? product.product_bundle : []
86
+ );
87
+ const originExtend = (_c = (_b = product.metadata) == null ? void 0 : _b.origin) == null ? void 0 : _c._extend;
70
88
  const other = {
71
89
  product_id: resolvedId,
72
90
  product_variant_id: product.product_variant_id ?? 0,
73
91
  option,
74
- bundle,
92
+ bundle: ((_d = originExtend == null ? void 0 : originExtend.other) == null ? void 0 : _d.bundle) ? JSON.parse(JSON.stringify(originExtend.other.bundle)) : bundle,
75
93
  quantity: product.num ?? 1
76
94
  };
77
95
  const skuValue = {
78
96
  product_id: resolvedId,
79
97
  product_variant_id: product.product_variant_id ?? 0,
80
- option,
81
- bundle
98
+ option: other.option,
99
+ bundle: other.bundle
82
100
  };
83
101
  const extend = {
84
102
  quantity: product.num ?? 1,
85
103
  product_name: (sourceProduct == null ? void 0 : sourceProduct.title) ?? "",
86
104
  note: product.note ?? "",
87
105
  // v2:_extend.price 为主商品 source 价;行 composite 用 total / origin_total 展示
88
- price: sourcePrice,
89
- total: selling,
90
- origin_total: original,
106
+ price: (originExtend == null ? void 0 : originExtend.price) ?? sourcePrice,
107
+ total: (originExtend == null ? void 0 : originExtend.total) ?? selling,
108
+ origin_total: (originExtend == null ? void 0 : originExtend.origin_total) ?? original,
91
109
  other,
92
110
  skuValue: JSON.parse(JSON.stringify(skuValue)),
93
111
  _skuValue: JSON.parse(JSON.stringify(skuValue)),
94
- isNormalProduct: true
112
+ isNormalProduct: true,
113
+ ...(originExtend == null ? void 0 : originExtend.priceOverride) !== void 0 ? { priceOverride: originExtend.priceOverride } : {},
114
+ ...(originExtend == null ? void 0 : originExtend.bundle_edit) !== void 0 ? { bundle_edit: originExtend.bundle_edit } : {}
95
115
  };
116
+ if ((originExtend == null ? void 0 : originExtend.skuValue) || (originExtend == null ? void 0 : originExtend._skuValue)) {
117
+ extend.skuValue = JSON.parse(
118
+ JSON.stringify(originExtend.skuValue || originExtend._skuValue)
119
+ );
120
+ extend._skuValue = JSON.parse(JSON.stringify(extend.skuValue));
121
+ }
96
122
  return {
97
123
  ...sourceProduct || {},
98
124
  id: resolvedId,
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
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
6
  import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions } from './types';
@@ -72,6 +72,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
72
72
  getLocalOrderByOrderNumber(orderNumber: string): Promise<Record<string, any> | null>;
73
73
  getLocalOrderByExternalSaleNumber(externalSaleNumber: string): Promise<Record<string, any> | null>;
74
74
  saveDraft(): Promise<void>;
75
+ private saveDraftInBackground;
75
76
  private hydrateTempOrderFromLocalRecord;
76
77
  private extractOrderIdFromSubmitResult;
77
78
  private calculatePaymentTotal;
@@ -103,7 +104,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
103
104
  updateTempOrderNote(note: string): string;
104
105
  updateTempOrderNote(note: string, sync: true): Promise<string>;
105
106
  updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
106
- private syncTempOrderNoteToRemote;
107
+ syncTempOrderNoteToRemote(orderId: number | string, note: string): Promise<string>;
107
108
  getTempOrderNote(): string;
108
109
  updateTempOrderShopDiscount(amount: string | number): string;
109
110
  updateTempOrderBuzzer(buzzer: string): string;
@@ -157,8 +158,14 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
157
158
  addProductToOrder(product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput): Promise<OrderProduct[]>;
158
159
  private hasGoodPassDiscount;
159
160
  updateOrderProduct(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
161
+ updateOrderProductQuantity(params: UpdateOrderProductQuantityParams): Promise<OrderProduct[]>;
160
162
  updateOrderBooking(params: UpdateOrderBookingParams): any[];
161
163
  removeProductFromOrder(identity: OrderProductIdentity): Promise<OrderProduct[]>;
164
+ /**
165
+ * 仅清空购物车行(products / bookings / discount_list),不重置整单。
166
+ * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
167
+ */
168
+ clearOrderCartLines(): Promise<OrderTempOrder>;
162
169
  /**
163
170
  * 提交当前 Sales tempOrder。
164
171
  *
@@ -235,4 +242,4 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
235
242
  getLastOrderInfo(): Record<string, any> | undefined;
236
243
  getOrderInfo(order_id: number): Promise<any>;
237
244
  }
238
- export type { UpdateOrderBookingParams, UpdateOrderProductParams } from './types';
245
+ export type { UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
@@ -495,6 +495,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
495
495
  });
496
496
  }
497
497
  }
498
+ saveDraftInBackground() {
499
+ void this.saveDraft();
500
+ }
498
501
  async hydrateTempOrderFromLocalRecord(record) {
499
502
  return this.hydrateTempOrderFromRecord(record);
500
503
  }
@@ -561,11 +564,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
561
564
  return newOrder;
562
565
  }
563
566
  restoreOrder() {
567
+ var _a, _b;
564
568
  const freshTempOrder = this.createDefaultTempOrderInstance();
565
569
  this.ensureExternalSaleNumber(freshTempOrder);
566
570
  this.store.tempOrder = freshTempOrder;
567
571
  this.store.summary = (0, import_utils.createEmptySummary)();
568
572
  this.store.lastOrderInfo = void 0;
573
+ void ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList([]));
574
+ void ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList([]));
569
575
  this.persistTempOrder();
570
576
  return freshTempOrder;
571
577
  }
@@ -911,11 +917,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
911
917
  extend.customerSnapshot = (0, import_lodash_es.cloneDeep)(snapshot);
912
918
  }
913
919
  this.persistTempOrder();
920
+ this.saveDraftInBackground();
914
921
  this.emitOrderCustomerChange();
915
922
  }
916
923
  getOrderCustomer() {
917
924
  const tempOrder = this.store.tempOrder;
918
- if (!tempOrder || tempOrder.customer_id === null || tempOrder.customer_id === void 0) {
925
+ if (!tempOrder || !tempOrder.customer_id) {
919
926
  return null;
920
927
  }
921
928
  return {
@@ -933,7 +940,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
933
940
  }
934
941
  clearOrderCustomer() {
935
942
  const tempOrder = this.ensureTempOrder();
936
- tempOrder.customer_id = null;
943
+ tempOrder.customer_id = 0;
937
944
  tempOrder.customer_name = "";
938
945
  tempOrder.country_calling_code = "";
939
946
  tempOrder.phone = "";
@@ -941,6 +948,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
941
948
  if (tempOrder._extend)
942
949
  delete tempOrder._extend.customerSnapshot;
943
950
  this.persistTempOrder();
951
+ this.saveDraftInBackground();
944
952
  this.core.effects.emit(import_types.OrderHooks.OnOrderCustomerChange, null);
945
953
  }
946
954
  emitOrderCustomerChange() {
@@ -1206,6 +1214,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1206
1214
  };
1207
1215
  if (unique_identification_number !== void 0) {
1208
1216
  identityLookup.unique_identification_number = unique_identification_number;
1217
+ if (identity_key === void 0) {
1218
+ identityLookup.identity_key = unique_identification_number;
1219
+ }
1209
1220
  }
1210
1221
  if (identity_key !== void 0) {
1211
1222
  identityLookup.identity_key = identity_key;
@@ -1214,7 +1225,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1214
1225
  identityLookup.product_option_item = product_option_item;
1215
1226
  if (product_bundle !== void 0)
1216
1227
  identityLookup.product_bundle = product_bundle;
1217
- const productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1228
+ let productIndex = -1;
1229
+ if (unique_identification_number !== void 0) {
1230
+ const targetUid = String(unique_identification_number);
1231
+ productIndex = tempOrder.products.findIndex((item) => {
1232
+ var _a2;
1233
+ return String(
1234
+ ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
1235
+ ) === targetUid;
1236
+ });
1237
+ }
1238
+ if (productIndex === -1) {
1239
+ productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1240
+ }
1218
1241
  if (productIndex === -1) {
1219
1242
  throw new Error("[Order] 目标商品不存在,无法更新");
1220
1243
  }
@@ -1281,6 +1304,65 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1281
1304
  this.persistTempOrder();
1282
1305
  return tempOrder.products;
1283
1306
  }
1307
+ async updateOrderProductQuantity(params) {
1308
+ var _a;
1309
+ const {
1310
+ product_id,
1311
+ product_variant_id,
1312
+ num,
1313
+ unique_identification_number,
1314
+ identity_key,
1315
+ product_option_item,
1316
+ product_bundle
1317
+ } = params;
1318
+ const tempOrder = this.ensureTempOrder();
1319
+ const identityLookup = {
1320
+ product_id,
1321
+ product_variant_id
1322
+ };
1323
+ if (unique_identification_number !== void 0) {
1324
+ identityLookup.unique_identification_number = unique_identification_number;
1325
+ if (identity_key === void 0) {
1326
+ identityLookup.identity_key = unique_identification_number;
1327
+ }
1328
+ }
1329
+ if (identity_key !== void 0)
1330
+ identityLookup.identity_key = identity_key;
1331
+ if (product_option_item !== void 0)
1332
+ identityLookup.product_option_item = product_option_item;
1333
+ if (product_bundle !== void 0)
1334
+ identityLookup.product_bundle = product_bundle;
1335
+ let productIndex = -1;
1336
+ if (unique_identification_number !== void 0) {
1337
+ const targetUid = String(unique_identification_number);
1338
+ productIndex = tempOrder.products.findIndex((item) => {
1339
+ var _a2;
1340
+ return String(
1341
+ ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
1342
+ ) === targetUid;
1343
+ });
1344
+ }
1345
+ if (productIndex === -1) {
1346
+ productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1347
+ }
1348
+ if (productIndex === -1) {
1349
+ throw new Error("[Order] 目标商品不存在,无法更新数量");
1350
+ }
1351
+ const targetProduct = tempOrder.products[productIndex];
1352
+ const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
1353
+ ...targetProduct,
1354
+ num: (0, import_utils3.getSafeProductNum)(num),
1355
+ metadata: {
1356
+ ...targetProduct.metadata || {},
1357
+ unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
1358
+ }
1359
+ });
1360
+ tempOrder.products[productIndex] = normalizedProduct;
1361
+ this.applyDiscount();
1362
+ await this.recalculateSummary({ createIfMissing: true });
1363
+ this.persistTempOrder();
1364
+ return tempOrder.products;
1365
+ }
1284
1366
  updateOrderBooking(params) {
1285
1367
  const { unique_identification_number, updates } = params;
1286
1368
  const tempOrder = this.ensureTempOrder();
@@ -1325,6 +1407,26 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1325
1407
  this.persistTempOrder();
1326
1408
  return tempOrder.products;
1327
1409
  }
1410
+ /**
1411
+ * 仅清空购物车行(products / bookings / discount_list),不重置整单。
1412
+ * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
1413
+ */
1414
+ async clearOrderCartLines() {
1415
+ const tempOrder = this.ensureTempOrder();
1416
+ tempOrder.products = [];
1417
+ tempOrder.bookings = [];
1418
+ tempOrder.discount_list = [];
1419
+ if (tempOrder._extend && typeof tempOrder._extend === "object") {
1420
+ tempOrder._extend = {
1421
+ ...tempOrder._extend,
1422
+ productsByUid: {}
1423
+ };
1424
+ }
1425
+ this.applyDiscount();
1426
+ await this.recalculateSummary({ createIfMissing: true });
1427
+ this.persistTempOrder();
1428
+ return tempOrder;
1429
+ }
1328
1430
  // ─── TempOrder: 提交 ───
1329
1431
  /**
1330
1432
  * 提交当前 Sales tempOrder。
@@ -1468,7 +1570,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1468
1570
  const submitResult = await this.submitTempOrder({
1469
1571
  payments: mappedPayments,
1470
1572
  paymentStatus: params.paymentStatus || "paid",
1471
- smallTicketDataFlag: params.smallTicketDataFlag
1573
+ smallTicketDataFlag: params.smallTicketDataFlag,
1574
+ channel: params.channel
1472
1575
  });
1473
1576
  return { isFullyPaid, submitResult };
1474
1577
  }
@@ -107,7 +107,7 @@ export interface OrderTempOrder {
107
107
  shop_order_number: string | null;
108
108
  shop_full_order_number: string | null;
109
109
  type: string;
110
- business_code: string;
110
+ business_code?: string;
111
111
  platform: string;
112
112
  sales_channel: string;
113
113
  order_sales_channel: string;
@@ -193,6 +193,11 @@ export interface UpdateOrderProductParams {
193
193
  product_bundle?: any[];
194
194
  booking?: AddProductBookingInput;
195
195
  }
196
+ /** 仅更新购物车行数量;行定位语义与 updateOrderProduct / removeProductFromOrder 保持一致 */
197
+ export interface UpdateOrderProductQuantityParams extends OrderProductIdentity {
198
+ num: number;
199
+ identity_key?: string;
200
+ }
196
201
  export interface UpdateOrderBookingParams {
197
202
  unique_identification_number: string;
198
203
  updates: AddProductBookingInput;
@@ -251,7 +256,7 @@ export interface SubmitSalesOrderParams {
251
256
  shop_order_number: string | null;
252
257
  shop_full_order_number: string | null;
253
258
  type: string;
254
- business_code: string;
259
+ business_code?: string;
255
260
  platform: string;
256
261
  request_unique_idempotency_token?: string;
257
262
  sales_channel: string;
@@ -362,6 +367,7 @@ export interface SyncPaymentsToOrderParams {
362
367
  paymentStatus?: SubmitSalesOrderParams['query']['payment_status'];
363
368
  submitWhenPaid?: boolean;
364
369
  smallTicketDataFlag?: number;
370
+ channel?: string;
365
371
  }
366
372
  export interface SyncPaymentsToOrderResult<T = any> {
367
373
  isFullyPaid: boolean;
@@ -482,6 +488,7 @@ export interface OrderModuleAPI {
482
488
  updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
483
489
  addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput) => Promise<OrderProduct[]>;
484
490
  updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
491
+ updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
485
492
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
486
493
  removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
487
494
  persistTempOrder: () => void;
@@ -65,6 +65,19 @@ export declare function sumOptionUnitPrice(options?: Array<{
65
65
  *
66
66
  * 导出为纯函数方便单测直接驱动钩子,不依赖 OrderModule 实例。
67
67
  */
68
+ /** Rules calcDiscount 用手动价标记;undefined 表示交给 Rules 用 total/origin_total 推断 */
69
+ export declare function resolveRulesManualDiscountFlag(metadata: Record<string, any> | null | undefined): boolean | undefined;
70
+ /**
71
+ * 手动改价(price_override)时行级 original_price(composite 单价):
72
+ * 购物车划线价应对齐 metadata.origin._extend.origin_total(改价前单价 composite,如 40),
73
+ * 而非 bundle 子项 catalog 原价合成的 composedOriginalPrice(如 30)。
74
+ *
75
+ * origin_total 与 SkuDetailModal / cacheItem._extend 一致,为单价语义,不再除以 num。
76
+ */
77
+ export declare function resolveManualOverrideLineOriginalPrice(params: {
78
+ num?: number;
79
+ metadata?: Record<string, any> | null;
80
+ }, fallbackCompositeOriginal: string): string;
68
81
  export declare function createDefaultOrderRulesHooks(): RulesParamsHooks;
69
82
  /**
70
83
  * 通过 session 类商品的开始时间结束时间生成商品的时长
@@ -47,6 +47,8 @@ __export(utils_exports, {
47
47
  normalizeBookingSubType: () => normalizeBookingSubType,
48
48
  normalizeSubmitBooking: () => normalizeSubmitBooking,
49
49
  normalizeSubmitCollectPaxValue: () => normalizeSubmitCollectPaxValue,
50
+ resolveManualOverrideLineOriginalPrice: () => resolveManualOverrideLineOriginalPrice,
51
+ resolveRulesManualDiscountFlag: () => resolveRulesManualDiscountFlag,
50
52
  resolveSubmitCollectPax: () => resolveSubmitCollectPax,
51
53
  sumOptionUnitPrice: () => sumOptionUnitPrice
52
54
  });
@@ -80,6 +82,35 @@ function sumOptionUnitPrice(options) {
80
82
  }
81
83
  return total;
82
84
  }
85
+ function resolveRulesManualDiscountFlag(metadata) {
86
+ if (!metadata)
87
+ return void 0;
88
+ if (metadata.is_manual_discount === true || metadata.is_manual_discount === 1) {
89
+ return true;
90
+ }
91
+ const priceOverride = metadata.price_override;
92
+ if (priceOverride !== void 0 && priceOverride !== null && priceOverride !== "") {
93
+ return true;
94
+ }
95
+ return void 0;
96
+ }
97
+ function resolveManualOverrideLineOriginalPrice(params, fallbackCompositeOriginal) {
98
+ var _a, _b;
99
+ const metadata = params.metadata || {};
100
+ const priceOverride = metadata.price_override;
101
+ if (priceOverride === void 0 || priceOverride === null || priceOverride === "") {
102
+ return fallbackCompositeOriginal;
103
+ }
104
+ const refTotal = (_b = (_a = metadata.origin) == null ? void 0 : _a._extend) == null ? void 0 : _b.origin_total;
105
+ if (refTotal === void 0 || refTotal === null || refTotal === "") {
106
+ return fallbackCompositeOriginal;
107
+ }
108
+ const parsed = Number(refTotal);
109
+ if (!Number.isFinite(parsed)) {
110
+ return fallbackCompositeOriginal;
111
+ }
112
+ return new import_decimal.default(parsed).toDecimalPlaces(2).toFixed(2);
113
+ }
83
114
  function createDefaultOrderRulesHooks() {
84
115
  const toUnitPriceString = (totalLike, num) => {
85
116
  const effectiveNum = Number(num) > 0 ? Number(num) : 1;
@@ -87,7 +118,7 @@ function createDefaultOrderRulesHooks() {
87
118
  };
88
119
  return {
89
120
  getProduct: (product) => {
90
- var _a, _b, _c, _d, _e, _f;
121
+ var _a, _b, _c, _d, _e;
91
122
  const metadataAny = product.metadata || {};
92
123
  const optionSum = sumOptionUnitPrice(product.product_option_item);
93
124
  let sourcePrice;
@@ -135,9 +166,11 @@ function createDefaultOrderRulesHooks() {
135
166
  bundle: product.product_bundle || [],
136
167
  booking_id: ((_b = product.metadata) == null ? void 0 : _b.booking_id) || null,
137
168
  isClient: false,
138
- isManualDiscount: ((_c = product.metadata) == null ? void 0 : _c.is_manual_discount) || false,
139
- holder_id: (_d = product.metadata) == null ? void 0 : _d.holder_id,
140
- startDate: ((_e = product.metadata) == null ? void 0 : _e.start_date) || ((_f = product.metadata) == null ? void 0 : _f.startDate)
169
+ // 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
170
+ // 无券时会把 bundle 价还原成 original_price(手动改价套餐会从 20 回到 30)。
171
+ isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
172
+ holder_id: (_c = product.metadata) == null ? void 0 : _c.holder_id,
173
+ startDate: ((_d = product.metadata) == null ? void 0 : _d.start_date) || ((_e = product.metadata) == null ? void 0 : _e.startDate)
141
174
  };
142
175
  },
143
176
  setProduct: (product, values) => {
@@ -160,10 +193,14 @@ function createDefaultOrderRulesHooks() {
160
193
  bundle: nextBundle,
161
194
  useOriginalBundle: true
162
195
  });
196
+ const finalOriginalPrice = resolveManualOverrideLineOriginalPrice(
197
+ { num: nextNum, metadata: metadataAny },
198
+ composedOriginalPrice
199
+ );
163
200
  return {
164
201
  ...product,
165
202
  selling_price: composedSellingPrice,
166
- original_price: composedOriginalPrice,
203
+ original_price: finalOriginalPrice,
167
204
  discount_list: values.discount_list ?? product.discount_list,
168
205
  num: values.quantity ?? product.num,
169
206
  product_bundle: nextBundle,
@@ -428,8 +465,8 @@ function createDefaultTempOrder(params) {
428
465
  order_number: null,
429
466
  shop_order_number: null,
430
467
  shop_full_order_number: null,
431
- type: "appointment_booking",
432
- business_code: "appointment_booking",
468
+ type: "",
469
+ business_code: void 0,
433
470
  platform: "h5",
434
471
  sales_channel: "my_pisel",
435
472
  order_sales_channel: "online_store",
@@ -471,6 +508,7 @@ function createDefaultTempOrder(params) {
471
508
  };
472
509
  }
473
510
  function buildSubmitPayload(params) {
511
+ var _a;
474
512
  const {
475
513
  tempOrder,
476
514
  cacheId,
@@ -503,6 +541,14 @@ function buildSubmitPayload(params) {
503
541
  holder_id: _holderId,
504
542
  ...tempOrderRest
505
543
  } = tempOrder;
544
+ let submitType = type ?? tempOrder.type;
545
+ if (!submitType) {
546
+ if ((_a = tempOrder == null ? void 0 : tempOrder.bookings) == null ? void 0 : _a.length) {
547
+ submitType = "appointment_booking";
548
+ } else {
549
+ submitType = "virtual";
550
+ }
551
+ }
506
552
  const payload = {
507
553
  ...tempOrderRest,
508
554
  order_number: null,
@@ -510,8 +556,8 @@ function buildSubmitPayload(params) {
510
556
  shop_full_order_number: null,
511
557
  platform: normalizeSubmitPlatform(platform),
512
558
  request_unique_idempotency_token: tempOrder.request_unique_idempotency_token || `${tempOrder.external_sale_number}_${now.getTime()}`,
513
- type: type ?? tempOrder.type ?? "table-order",
514
- business_code: businessCode ?? tempOrder.business_code ?? "table-order",
559
+ type: submitType,
560
+ business_code: businessCode ?? tempOrder.business_code,
515
561
  sales_channel: tempOrder.sales_channel || "my_pisel",
516
562
  order_sales_channel: channel ?? tempOrder.order_sales_channel ?? "online_store",
517
563
  status: tempOrder.status || "normal",
@@ -632,6 +678,8 @@ function formatV1Product(products) {
632
678
  normalizeBookingSubType,
633
679
  normalizeSubmitBooking,
634
680
  normalizeSubmitCollectPaxValue,
681
+ resolveManualOverrideLineOriginalPrice,
682
+ resolveRulesManualDiscountFlag,
635
683
  resolveSubmitCollectPax,
636
684
  sumOptionUnitPrice
637
685
  });
@@ -1870,6 +1870,7 @@ var Server = class {
1870
1870
  return;
1871
1871
  searchParams.append("with[]", String(field));
1872
1872
  });
1873
+ searchParams.append("lookup_mode", "multi");
1873
1874
  const query = searchParams.toString();
1874
1875
  return `/shop/order/sales/${encodeURIComponent(orderId)}${query ? `?${query}` : ""}`;
1875
1876
  }
@@ -1,6 +1,6 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
- import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesCalculateProductBookingPriceParams, BaseSalesProductBookingPriceResult, BaseSalesScanCodeResult } from './types';
3
+ import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesProductBookingPriceResult, BaseSalesScanCodeResult } from './types';
4
4
  import { OrderModule } from '../../modules/Order';
5
5
  import type { AddProductBookingInput, LoadSalesDetailParams, OrderPaymentData, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder } from '../../modules/Order/types';
6
6
  import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
@@ -110,15 +110,22 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
110
110
  updateTempOrderNote(note: string): string;
111
111
  updateTempOrderNote(note: string, sync: true): Promise<string>;
112
112
  updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
113
+ updateRemoteOrderNote(orderId: number | string, note: string): void;
113
114
  updateTempOrderShopDiscount(amount: string | number): string;
114
115
  updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
115
116
  private ensureTempOrder;
116
117
  addNewOrder(): Promise<OrderTempOrder>;
117
118
  saveDraft(): Promise<void>;
118
119
  restoreOrder(): Promise<OrderTempOrder>;
120
+ /**
121
+ * 仅清空 tempOrder 购物车行(products / bookings / discount_list)。
122
+ * 同步清空内存中的 salesDetail 商品/预约视图,避免编辑态仍读到旧 bookings。
123
+ */
124
+ clearOrderCartLines(): Promise<OrderTempOrder>;
119
125
  getOrderProducts(): import("../../modules/Order/types").OrderProduct[];
120
126
  getSummary(): Promise<import("../../modules/Order/types").OrderSummary>;
121
127
  private getHistoricalProductDiscountList;
128
+ private isPersistedOrderProduct;
122
129
  private mergeHistoricalDiscountList;
123
130
  loadDiscountConfig(params?: {
124
131
  customerId?: number;
@@ -215,6 +222,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
215
222
  calculateProductBookingPrice(params: BaseSalesCalculateProductBookingPriceParams): Promise<BaseSalesProductBookingPriceResult>;
216
223
  addProductToOrder(product: Partial<BaseSalesOrderProduct> & BaseSalesOrderProductIdentity, booking?: AddProductBookingInput): Promise<import("../../modules/Order/types").OrderProduct[]>;
217
224
  updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
225
+ updateOrderProductQuantity(params: BaseSalesUpdateOrderProductQuantityParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
218
226
  updateOrderBooking(params: UpdateOrderBookingParams): any[];
219
227
  /**
220
228
  * 设置单行商品备注(与整单 `updateTempOrderNote` 区分)。