@pisell/pisellos 2.2.273 → 2.2.275

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 (74) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +12 -10
  3. package/dist/modules/Order/index.d.ts +7 -6
  4. package/dist/modules/Order/index.js +217 -115
  5. package/dist/modules/Order/types.d.ts +23 -3
  6. package/dist/modules/Order/types.js +11 -0
  7. package/dist/modules/Payment/index.js +1 -1
  8. package/dist/modules/Payment/types.d.ts +81 -4
  9. package/dist/modules/Payment/types.js +18 -3
  10. package/dist/modules/Payment/walletpass.d.ts +38 -1
  11. package/dist/modules/Payment/walletpass.js +917 -114
  12. package/dist/modules/Rules/index.d.ts +2 -0
  13. package/dist/modules/Rules/index.js +78 -64
  14. package/dist/modules/SalesSummary/utils.js +7 -1
  15. package/dist/server/index.d.ts +4 -0
  16. package/dist/server/index.js +27 -18
  17. package/dist/server/modules/index.d.ts +1 -1
  18. package/dist/server/modules/order/index.d.ts +16 -0
  19. package/dist/server/modules/order/index.js +964 -776
  20. package/dist/server/modules/order/types.d.ts +14 -0
  21. package/dist/server/modules/order/types.js +6 -0
  22. package/dist/solution/BaseSales/index.d.ts +80 -15
  23. package/dist/solution/BaseSales/index.js +1498 -444
  24. package/dist/solution/BaseSales/types.d.ts +55 -1
  25. package/dist/solution/BaseSales/types.js +2 -1
  26. package/dist/solution/BaseSales/utils/cartPromotion.js +8 -3
  27. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  28. package/dist/solution/BookingByStep/index.d.ts +1 -1
  29. package/dist/solution/BookingTicket/index.d.ts +1 -1
  30. package/dist/solution/BookingTicket/index.js +12 -3
  31. package/dist/solution/BookingTicket/types.d.ts +4 -0
  32. package/dist/solution/BookingTicket/utils/cartView.js +44 -32
  33. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  34. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  35. package/dist/solution/Sales/index.d.ts +1 -0
  36. package/dist/solution/Sales/index.js +16 -2
  37. package/dist/solution/VenueBooking/index.d.ts +1 -0
  38. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  39. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -1
  40. package/lib/modules/Order/index.d.ts +7 -6
  41. package/lib/modules/Order/index.js +127 -20
  42. package/lib/modules/Order/types.d.ts +23 -3
  43. package/lib/modules/Payment/index.js +1 -1
  44. package/lib/modules/Payment/types.d.ts +81 -4
  45. package/lib/modules/Payment/types.js +4 -3
  46. package/lib/modules/Payment/walletpass.d.ts +38 -1
  47. package/lib/modules/Payment/walletpass.js +730 -21
  48. package/lib/modules/Rules/index.d.ts +2 -0
  49. package/lib/modules/Rules/index.js +24 -14
  50. package/lib/modules/SalesSummary/utils.js +5 -1
  51. package/lib/server/index.d.ts +4 -0
  52. package/lib/server/index.js +14 -6
  53. package/lib/server/modules/index.d.ts +1 -1
  54. package/lib/server/modules/order/index.d.ts +16 -0
  55. package/lib/server/modules/order/index.js +140 -4
  56. package/lib/server/modules/order/types.d.ts +14 -0
  57. package/lib/server/modules/order/types.js +1 -0
  58. package/lib/solution/BaseSales/index.d.ts +80 -15
  59. package/lib/solution/BaseSales/index.js +712 -48
  60. package/lib/solution/BaseSales/types.d.ts +55 -1
  61. package/lib/solution/BaseSales/types.js +2 -1
  62. package/lib/solution/BaseSales/utils/cartPromotion.js +8 -2
  63. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  64. package/lib/solution/BookingByStep/index.d.ts +1 -1
  65. package/lib/solution/BookingTicket/index.d.ts +1 -1
  66. package/lib/solution/BookingTicket/index.js +4 -1
  67. package/lib/solution/BookingTicket/types.d.ts +4 -0
  68. package/lib/solution/BookingTicket/utils/cartView.js +43 -30
  69. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  70. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  71. package/lib/solution/Sales/index.d.ts +1 -0
  72. package/lib/solution/Sales/index.js +15 -3
  73. package/lib/solution/VenueBooking/index.d.ts +1 -0
  74. package/package.json +1 -1
@@ -3,6 +3,7 @@ import { OrderModule, ProductList, QuotationModule, SalesSummaryModule, ScanOrde
3
3
  import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderConfig as BaseSalesLoggerProviderConfig, ScanOrderLoggerProviderType as BaseSalesLoggerProviderType } from '../../modules/ScanOrderLogger/types';
4
4
  import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
5
5
  import type { QuotationCustomerScopeInfo } from '../../modules/Quotation/types';
6
+ import type { PaymentMethod } from '../../modules/Payment/types';
6
7
  /**
7
8
  * BaseSales 流程 hook 后缀。
8
9
  * 完整事件名应由当前模块名动态拼接,避免多个实例共享固定事件 key。
@@ -16,11 +17,62 @@ export declare const BaseSalesHookNames: {
16
17
  readonly onPaymentSyncStart: "onPaymentSyncStart";
17
18
  readonly onPaymentSyncEnd: "onPaymentSyncEnd";
18
19
  readonly onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd";
20
+ readonly onWalletAssetsStateChanged: "onWalletAssetsStateChanged";
19
21
  };
20
22
  export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSalesHookNames];
21
23
  export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
22
24
  export type BaseSalesStatus = 'idle' | 'initializing' | 'ready' | 'error';
23
25
  export type BaseSalesPaymentStatus = 'paid' | 'partially_paid' | 'unpaid' | 'payment_processing' | string;
26
+ export interface BaseSalesCashPaymentConfig {
27
+ available: boolean;
28
+ paymentMethod?: PaymentMethod;
29
+ amountDue: number;
30
+ recommendedAmounts: number[];
31
+ }
32
+ export interface BaseSalesPayCashParams {
33
+ /** 实际计入订单的现金支付金额(部分支付时小于待付金额)。 */
34
+ amount: number;
35
+ /** 顾客实际交付现金;可大于 amount。 */
36
+ actualPaidAmount?: number;
37
+ changeAmount?: number;
38
+ roundingAmount?: number;
39
+ }
40
+ export interface BaseSalesPayCashResult {
41
+ payment: Record<string, any>;
42
+ payments: Record<string, any>[];
43
+ syncResult: Record<string, any>;
44
+ isOrderFullyPaid: boolean;
45
+ }
46
+ export interface BaseSalesCommitPaymentMethodParams {
47
+ /** 支付方式 id;与 paymentMethodCode 至少传一个。 */
48
+ paymentMethodId?: number | string;
49
+ /** 支付方式 code,大小写不敏感。 */
50
+ paymentMethodCode?: string;
51
+ /** 本次计入订单的支付金额。 */
52
+ amount: number;
53
+ /** 支付设备返回的原始金额;缺省时与 amount 相同。 */
54
+ originAmount?: number;
55
+ /** 支付设备返回的实际手续费配置。 */
56
+ serviceCharge?: {
57
+ amount?: string | number;
58
+ percentage?: string | number;
59
+ } | null;
60
+ /** 支付设备返回的唯一流水号等扩展信息。 */
61
+ metadata?: Record<string, any>;
62
+ /** 少数支付方式需要透传的额外 payment 字段。 */
63
+ paymentData?: Record<string, any>;
64
+ }
65
+ export interface BaseSalesCommitPaymentMethodResult {
66
+ payment: Record<string, any>;
67
+ payments: Record<string, any>[];
68
+ syncResult: Record<string, any>;
69
+ isOrderFullyPaid: boolean;
70
+ }
71
+ export interface BaseSalesConfirmWalletPaymentResult<T = Record<string, any>> {
72
+ submitResult: T;
73
+ payments: Record<string, any>[];
74
+ isOrderFullyPaid: boolean;
75
+ }
24
76
  export interface BaseSalesEntryContext {
25
77
  biz: string;
26
78
  mode: 'scan' | 'append';
@@ -387,8 +439,10 @@ export interface BaseSalesAddLogParams extends BaseSalesLogInput {
387
439
  /** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList 或 scannedDiscountList 补 Holder) */
388
440
  export interface BaseSalesScanCodeResult {
389
441
  isAvailable: boolean;
442
+ /** 卡券已加入 Promotion;false 时可能是无效、过期或已使用。 */
443
+ isAccepted?: boolean;
390
444
  type?: 'server' | string;
391
445
  unavailableReason?: 'time_limit' | string;
392
- /** batchSearch 原始结果;isAvailable=false 时 discountList 可能未写入 store,Holder 补全需读此字段 */
446
+ /** batchSearch 原始结果;Holder 补全等流程可从这里读取原始卡券。 */
393
447
  scannedDiscountList?: Discount[];
394
448
  }
@@ -31,7 +31,8 @@ var BaseSalesHookNames = {
31
31
  onCartValidationChanged: "onCartValidationChanged",
32
32
  onPaymentSyncStart: "onPaymentSyncStart",
33
33
  onPaymentSyncEnd: "onPaymentSyncEnd",
34
- onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd"
34
+ onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd",
35
+ onWalletAssetsStateChanged: "onWalletAssetsStateChanged"
35
36
  };
36
37
  function createBaseSalesHook(moduleName, hookName) {
37
38
  return `${moduleName}:${hookName}`;
@@ -367,8 +367,14 @@ function getProductLineNoteSignature(product) {
367
367
  return uid ? `note:${uid}` : `note:${normalizedNote}`;
368
368
  }
369
369
  function getPromotionLineMergeBoundary(product) {
370
- var _a;
371
- if (((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_edit_for_runtime) !== true)
370
+ var _a, _b;
371
+ if ((product == null ? void 0 : product.product_id) === void 0 || (product == null ? void 0 : product.product_id) === null) {
372
+ return `custom:${getOrderProductUid(product)}`;
373
+ }
374
+ if (Number(((_a = product == null ? void 0 : product.product_sku) == null ? void 0 : _a.open_sold_weight) || 0) === 1) {
375
+ return `weighing:${getOrderProductUid(product)}`;
376
+ }
377
+ if (((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_edit_for_runtime) !== true)
372
378
  return "";
373
379
  return `edit:${getOrderProductUid(product)}`;
374
380
  }
@@ -132,14 +132,15 @@ function transformBaseProductToOrderProduct(params) {
132
132
  ...callbackOrigin || {}
133
133
  };
134
134
  const matchedVariant = findVariantById(callbackOrigin, productVariantId) ?? findVariantById(sourceProduct, productVariantId) ?? findVariantById(origin, productVariantId);
135
+ const hasPriceOverride = payload.price_override !== void 0 && payload.price_override !== null && payload.price_override !== "";
136
+ const catalogSourcePrice = (matchedVariant == null ? void 0 : matchedVariant.price) ?? (matchedVariant == null ? void 0 : matchedVariant.base_price) ?? (origin == null ? void 0 : origin.price) ?? (origin == null ? void 0 : origin.base_price) ?? (sourceProduct == null ? void 0 : sourceProduct.price) ?? (sourceProduct == null ? void 0 : sourceProduct.selling_price) ?? (sourceProduct == null ? void 0 : sourceProduct.base_price);
135
137
  const sourceProductPrice = toPriceString(
136
- payload.price ?? payload.selling_price ?? (matchedVariant == null ? void 0 : matchedVariant.price) ?? (matchedVariant == null ? void 0 : matchedVariant.base_price) ?? (origin == null ? void 0 : origin.price) ?? (origin == null ? void 0 : origin.base_price) ?? (sourceProduct == null ? void 0 : sourceProduct.price) ?? (sourceProduct == null ? void 0 : sourceProduct.selling_price) ?? (sourceProduct == null ? void 0 : sourceProduct.base_price),
138
+ hasPriceOverride ? catalogSourcePrice ?? payload.price ?? payload.selling_price : payload.price ?? payload.selling_price ?? catalogSourcePrice,
137
139
  "0.00"
138
140
  );
139
141
  const explicitLineTotal = payload.line_total ?? payload.total ?? ((_c = payload._extend) == null ? void 0 : _c.total);
140
142
  const hasExplicitLineTotal = Number.isFinite(Number(explicitLineTotal));
141
143
  const lineCompositeTotal = toPriceString(explicitLineTotal, sourceProductPrice);
142
- const hasPriceOverride = payload.price_override !== void 0 && payload.price_override !== null && payload.price_override !== "";
143
144
  const productOptionItem = (0, import_utils.normalizeProductSkuOptions)(
144
145
  normalizeOptionItems(
145
146
  ((_d = payload.product_sku) == null ? void 0 : _d.option) ?? payload.option ?? payload.options ?? payload.product_option_item
@@ -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 | 2 | 1 | 6 | 4 | 5 | 3;
314
+ weekNum: 0 | 2 | 1 | 5 | 4 | 3 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -326,7 +326,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
326
326
  * 获取当前的客户搜索条件
327
327
  * @returns 当前搜索条件
328
328
  */
329
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
329
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
330
330
  /**
331
331
  * 获取客户列表状态(包含滚动加载相关状态)
332
332
  * @returns 客户状态
@@ -368,6 +368,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
368
368
  }
369
369
  return {
370
370
  isAvailable: raw.isAvailable,
371
+ ...raw.isAccepted !== void 0 ? { isAccepted: raw.isAccepted } : {},
371
372
  type: raw.type,
372
373
  unavailableReason: raw.unavailableReason,
373
374
  scannedDiscountList: raw.scannedDiscountList
@@ -1440,7 +1441,9 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1440
1441
  decideAddProduct: (item, options) => this.decideAddProduct(item, options),
1441
1442
  decideAfterDetail: (cacheItem, options) => this.decideAfterDetail(cacheItem, options),
1442
1443
  transformDetailToProductAndBooking: (input) => this.transformDetailToProductAndBooking(input),
1443
- addProductToOrder: (product, booking) => this.addProductToOrder(product, booking)
1444
+ addProductToOrder: (product, booking) => this.addProductToOrder(product, booking),
1445
+ refreshWalletAssets: (params) => this.refreshWalletAssets(params),
1446
+ scanWalletAsset: (scanCode) => this.scanWalletAsset(scanCode)
1444
1447
  },
1445
1448
  formatted,
1446
1449
  bridge
@@ -118,12 +118,15 @@ export interface BookingTicketCartBookingView extends ISalesBooking {
118
118
  canAddTime: boolean;
119
119
  };
120
120
  }
121
+ export type BookingTicketCartLineView = BookingTicketCartBookingView | BookingTicketCartItemView;
121
122
  /**
122
123
  * BookingTicket 面向 UI 的购物车视图。
123
124
  */
124
125
  export interface BookingTicketCartView {
125
126
  bookings: BookingTicketCartBookingView[];
126
127
  items: BookingTicketCartItemView[];
128
+ /** 以 tempOrder.products 为唯一顺序真源的统一购物车行(旧到新)。 */
129
+ lines: BookingTicketCartLineView[];
127
130
  }
128
131
  /**
129
132
  * BookingTicket 面向 UI 的客户展示视图。
@@ -229,6 +232,7 @@ export interface GlobalScanHostBridge {
229
232
  */
230
233
  applyPromotionCode?: (code: string, customerId?: number) => Promise<{
231
234
  isAvailable?: boolean;
235
+ isAccepted?: boolean;
232
236
  type?: string;
233
237
  unavailableReason?: string;
234
238
  }>;
@@ -86,29 +86,27 @@ function isGiftProductLine(line) {
86
86
  function buildCartView(lines, bookings, options = {}) {
87
87
  const productLines = Array.isArray(lines) ? lines : [];
88
88
  const bookingList = Array.isArray(bookings) ? bookings : [];
89
+ const childBookings = bookingList.filter((booking) => booking.parent_id !== 0);
90
+ const bookingsByProductUid = indexBookingsByProductUid(childBookings);
89
91
  const linesByUid = indexProductsByUid(productLines);
90
92
  const addTimeLinesByBookingUid = indexAddTimeProductsByBookingUid(productLines);
91
- const claimedUids = /* @__PURE__ */ new Set();
92
93
  const claimedAddTimeLines = /* @__PURE__ */ new Set();
93
- const cartBookings = bookingList.filter((booking) => booking.parent_id !== 0).reduce((acc, booking) => {
94
- const uid = booking == null ? void 0 : booking.product_uid;
94
+ childBookings.forEach((booking) => {
95
+ const bookingUid = getBookingUid(booking);
96
+ if (!bookingUid)
97
+ return;
98
+ (addTimeLinesByBookingUid[bookingUid] || []).forEach((line) => {
99
+ claimedAddTimeLines.add(line);
100
+ });
101
+ });
102
+ const claimedBookings = /* @__PURE__ */ new Set();
103
+ const cartBookings = [];
104
+ const items = [];
105
+ const orderedLines = [];
106
+ const buildBookingView = (booking, product) => {
95
107
  const bookingUid = getBookingUid(booking);
96
- let product = null;
97
- if (uid !== void 0 && uid !== null && uid !== "") {
98
- const key = String(uid);
99
- if (!claimedUids.has(key)) {
100
- const line = linesByUid[key];
101
- if (isGiftProductLine(line))
102
- return acc;
103
- if (line) {
104
- claimedUids.add(key);
105
- product = line;
106
- }
107
- }
108
- }
109
108
  const addTimeProduct = bookingUid ? addTimeLinesByBookingUid[bookingUid] || [] : [];
110
- addTimeProduct.forEach((line) => claimedAddTimeLines.add(line));
111
- acc.push({
109
+ return {
112
110
  ...booking,
113
111
  _extend: {
114
112
  product,
@@ -122,21 +120,36 @@ function buildCartView(lines, bookings, options = {}) {
122
120
  shopOpeningHours: options.shopOpeningHours
123
121
  })
124
122
  }
125
- });
126
- return acc;
127
- }, []);
128
- const items = productLines.filter((line) => {
123
+ };
124
+ };
125
+ productLines.forEach((line) => {
129
126
  var _a;
130
- if (isGiftProductLine(line))
131
- return false;
132
- if (claimedAddTimeLines.has(line))
133
- return false;
127
+ if (isGiftProductLine(line) || claimedAddTimeLines.has(line))
128
+ return;
134
129
  const uid = (_a = line.metadata) == null ? void 0 : _a.unique_identification_number;
135
- if (uid === void 0 || uid === null || uid === "")
136
- return true;
137
- return !claimedUids.has(String(uid));
130
+ const matchedBooking = uid === void 0 || uid === null || uid === "" ? void 0 : (bookingsByProductUid[String(uid)] || []).find(
131
+ (booking) => !claimedBookings.has(booking)
132
+ );
133
+ if (matchedBooking) {
134
+ claimedBookings.add(matchedBooking);
135
+ const bookingView = buildBookingView(matchedBooking, line);
136
+ cartBookings.push(bookingView);
137
+ orderedLines.push(bookingView);
138
+ return;
139
+ }
140
+ items.push(line);
141
+ orderedLines.push(line);
142
+ });
143
+ childBookings.forEach((booking) => {
144
+ if (claimedBookings.has(booking))
145
+ return;
146
+ const uid = booking == null ? void 0 : booking.product_uid;
147
+ const linkedProduct = uid === void 0 || uid === null || uid === "" ? null : linesByUid[String(uid)] || null;
148
+ if (isGiftProductLine(linkedProduct))
149
+ return;
150
+ cartBookings.push(buildBookingView(booking, null));
138
151
  });
139
- return { bookings: cartBookings, items };
152
+ return { bookings: cartBookings, items, lines: orderedLines };
140
153
  }
141
154
  function isWalkInCustomer(customer) {
142
155
  if (!customer)
@@ -24,6 +24,14 @@ export interface GlobalScanApplyHost {
24
24
  cacheItem: any;
25
25
  };
26
26
  addProductToOrder(product: any, booking?: any): Promise<any>;
27
+ refreshWalletAssets?(params?: {
28
+ preserveSelection?: boolean;
29
+ }): Promise<any>;
30
+ scanWalletAsset?(code: string): Promise<{
31
+ type: 'walletCode' | 'normalCode';
32
+ asset?: any;
33
+ selected: boolean;
34
+ }>;
27
35
  }
28
36
  /**
29
37
  * 应用全局扫码格式化结果:设客户 / 加车 / 开单 / 弹窗链。
@@ -101,23 +101,55 @@ async function applyGlobalScan(host, formatted, bridge) {
101
101
  return { status: "success", kind: "customer" };
102
102
  }
103
103
  if (searchType === "walletPass") {
104
- if (!data) {
105
- (_c = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _c.call(bridge, "fail", "pisell2.text.scan-global-failed");
106
- return { status: "failed", reason: "invalid_data" };
107
- }
108
104
  const snapshot = host.getOrderCustomerSnapshot();
109
105
  const scannedCustomerIsWalkIn = (0, import_cartView.isWalkInCustomer)(data);
106
+ const trySelectWalletAsset = async () => {
107
+ var _a2, _b2;
108
+ if (!host.scanWalletAsset)
109
+ return null;
110
+ const walletResult = await host.scanWalletAsset(scanCode).catch((error) => {
111
+ console.warn("[GlobalScan] Wallet asset lookup failed", error);
112
+ return null;
113
+ });
114
+ if (!walletResult)
115
+ return null;
116
+ if (walletResult.type !== "normalCode" || !walletResult.asset) {
117
+ return null;
118
+ }
119
+ if (walletResult.selected) {
120
+ (_a2 = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _a2.call(bridge, "success");
121
+ return { status: "success", kind: "promotion" };
122
+ }
123
+ (_b2 = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _b2.call(bridge, "fail", "pisell2.text.goodpass.code-invalid-cart");
124
+ return { status: "failed", reason: "invalid_data" };
125
+ };
110
126
  if ((0, import_cartView.isWalkInCustomer)(snapshot) || scannedCustomerIsWalkIn) {
127
+ const walletSelection2 = await trySelectWalletAsset();
128
+ if (walletSelection2)
129
+ return walletSelection2;
111
130
  if (!(bridge == null ? void 0 : bridge.applyPromotionCode)) {
112
131
  return { status: "failed", reason: "no_bridge" };
113
132
  }
114
133
  const result = await bridge.applyPromotionCode(scanCode);
115
- if (result == null ? void 0 : result.isAvailable) {
134
+ if ((result == null ? void 0 : result.isAccepted) ?? (result == null ? void 0 : result.isAvailable)) {
116
135
  return { status: "success", kind: "promotion" };
117
136
  }
118
137
  return { status: "failed", reason: "invalid_data" };
119
138
  }
120
139
  host.setOrderCustomer(data);
140
+ await ((_c = host.refreshWalletAssets) == null ? void 0 : _c.call(host, { preserveSelection: false }));
141
+ const walletSelection = await trySelectWalletAsset();
142
+ if (walletSelection)
143
+ return walletSelection;
144
+ if (bridge == null ? void 0 : bridge.applyPromotionCode) {
145
+ const promotionResult = await bridge.applyPromotionCode(
146
+ scanCode,
147
+ Number((data == null ? void 0 : data.id) ?? (data == null ? void 0 : data.customer_id)) || void 0
148
+ );
149
+ if ((promotionResult == null ? void 0 : promotionResult.isAccepted) ?? (promotionResult == null ? void 0 : promotionResult.isAvailable)) {
150
+ return { status: "success", kind: "promotion" };
151
+ }
152
+ }
121
153
  (_d = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _d.call(bridge, "success", "pisell2.text.add-client-success");
122
154
  return { status: "success", kind: "customer" };
123
155
  }
@@ -95,6 +95,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
95
95
  * 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
96
96
  * 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
97
97
  * 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
98
+ * - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
98
99
  */
99
100
  private pickBookingsForCurrentPoint;
100
101
  /**
@@ -316,8 +316,9 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
316
316
  * 2) 若无 active,返回已超时且仍占用中的预约(允许并发多条)
317
317
  * 3) 若仍无,返回最近一组未来预约(同 start_time 的并发预约全部返回)
318
318
  * 4) 最后兜底返回一条(避免资源有历史预约时完全无反馈)
319
+ * - includeAllFuture 时,保留选中预约并返回当天全部后续预约;仅详情接口启用。
319
320
  */
320
- pickBookingsForCurrentPoint(current, bookings) {
321
+ pickBookingsForCurrentPoint(current, bookings, options = {}) {
321
322
  if (bookings.length === 0)
322
323
  return [];
323
324
  const currentDayStart = current.startOf("day");
@@ -334,6 +335,13 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
334
335
  const appendNextStartGroupIfNeeded = (selectedBookings) => {
335
336
  if (selectedBookings.length === 0)
336
337
  return selectedBookings;
338
+ if (options.includeAllFuture) {
339
+ const allFutureBookings = dayScopedBookings.filter((booking) => {
340
+ const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
341
+ return startAt.isValid() && startAt.isAfter(current);
342
+ });
343
+ return [...selectedBookings, ...allFutureBookings];
344
+ }
337
345
  const shouldAppendNextGroup = selectedBookings.some(
338
346
  (booking) => booking.status === "reserved" || booking.status === "occupied"
339
347
  );
@@ -384,6 +392,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
384
392
  return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, "day");
385
393
  });
386
394
  if (upcoming.length > 0) {
395
+ if (options.includeAllFuture)
396
+ return upcoming;
387
397
  const firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
388
398
  const upcomingStartGroup = upcoming.filter((booking) => {
389
399
  const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
@@ -638,7 +648,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
638
648
  const unpaidBookingList = matchedBookingList.filter((booking) => this.isUnpaidBooking(booking));
639
649
  const bookings = this.pickBookingsForCurrentPoint(
640
650
  current,
641
- this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
651
+ this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList),
652
+ { includeAllFuture: true }
642
653
  );
643
654
  const completedBookings = completedBookingList.map((booking) => {
644
655
  return {
@@ -654,7 +665,8 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
654
665
  });
655
666
  const unpaidBookings = this.pickBookingsForCurrentPoint(
656
667
  current,
657
- this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList)
668
+ this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList),
669
+ { includeAllFuture: true }
658
670
  );
659
671
  const orderCount = this.countBookingOrders(statsBookingList);
660
672
  const bookingCount = statsBookingList.length;
@@ -152,6 +152,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
152
152
  private recalculateOrderPricesFromQuotation;
153
153
  scanCode(code: string, customerId?: number): Promise<{
154
154
  isAvailable: boolean;
155
+ isAccepted?: boolean | undefined;
155
156
  discountList: import("../../modules/Discount").Discount[];
156
157
  type: "server" | "clientCalc";
157
158
  unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.273",
4
+ "version": "2.2.275",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",