@pisell/pisellos 2.2.278 → 2.2.280

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 (188) hide show
  1. package/dist/modules/BaseModule.d.ts +1 -0
  2. package/dist/modules/BaseModule.js +24 -28
  3. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  4. package/dist/modules/BookingContext/utils/productExtend.js +5 -9
  5. package/dist/modules/BookingContext/utils/timeSlices.js +24 -3
  6. package/dist/modules/Customer/index.d.ts +4 -0
  7. package/dist/modules/Customer/index.js +91 -59
  8. package/dist/modules/Customer/types.d.ts +2 -0
  9. package/dist/modules/Discount/index.d.ts +1 -0
  10. package/dist/modules/Discount/index.js +40 -11
  11. package/dist/modules/Discount/types.d.ts +1 -0
  12. package/dist/modules/Holder/index.d.ts +48 -0
  13. package/dist/modules/Holder/index.js +640 -0
  14. package/dist/modules/Holder/types.d.ts +123 -0
  15. package/dist/modules/Holder/types.js +1 -0
  16. package/dist/modules/Holder/utils.d.ts +13 -0
  17. package/dist/modules/Holder/utils.js +34 -0
  18. package/dist/modules/OpenData/index.js +2 -2
  19. package/dist/modules/Order/index.d.ts +32 -4
  20. package/dist/modules/Order/index.js +868 -675
  21. package/dist/modules/Order/types.d.ts +22 -1
  22. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  23. package/dist/modules/Order/utils/discountProductLineIdentity.js +227 -0
  24. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  25. package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
  26. package/dist/modules/Order/utils.d.ts +10 -0
  27. package/dist/modules/Order/utils.js +71 -34
  28. package/dist/modules/Payment/index.d.ts +4 -0
  29. package/dist/modules/Payment/index.js +14 -4
  30. package/dist/modules/Payment/walletpass.js +21 -7
  31. package/dist/modules/Product/types.d.ts +1 -0
  32. package/dist/modules/ProductList/index.js +33 -13
  33. package/dist/modules/Quotation/index.d.ts +1 -1
  34. package/dist/modules/Quotation/index.js +2 -2
  35. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  36. package/dist/modules/ResourcePlanner/index.js +181 -0
  37. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  38. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  39. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  40. package/dist/modules/ResourcePlanner/types.js +1 -0
  41. package/dist/modules/Rules/index.js +153 -56
  42. package/dist/modules/SalesSummary/index.js +12 -13
  43. package/dist/modules/ScanOrderLogger/index.d.ts +2 -0
  44. package/dist/modules/ScanOrderLogger/index.js +15 -2
  45. package/dist/modules/ScanOrderLogger/providers/feishu.js +45 -27
  46. package/dist/modules/ScanOrderLogger/types.d.ts +1 -0
  47. package/dist/modules/Schedule/index.d.ts +3 -1
  48. package/dist/modules/Schedule/index.js +21 -16
  49. package/dist/modules/Summary/utils.js +38 -13
  50. package/dist/modules/index.d.ts +2 -0
  51. package/dist/modules/index.js +3 -1
  52. package/dist/plugins/window.d.ts +1 -0
  53. package/dist/server/index.d.ts +20 -0
  54. package/dist/server/index.js +1101 -909
  55. package/dist/server/modules/order/index.d.ts +2 -0
  56. package/dist/server/modules/order/index.js +261 -96
  57. package/dist/server/modules/order/types.d.ts +1 -1
  58. package/dist/solution/BaseSales/index.d.ts +20 -1
  59. package/dist/solution/BaseSales/index.js +989 -881
  60. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -1
  61. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  62. package/dist/solution/BaseSales/utils.js +31 -20
  63. package/dist/solution/BookingByStep/index.d.ts +17 -2
  64. package/dist/solution/BookingByStep/index.js +294 -215
  65. package/dist/solution/BookingByStep/types.d.ts +2 -1
  66. package/dist/solution/BookingByStep/types.js +3 -1
  67. package/dist/solution/BookingByStep/utils/capacity.js +17 -1
  68. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  69. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  70. package/dist/solution/BookingTicket/index.d.ts +21 -3
  71. package/dist/solution/BookingTicket/index.js +312 -226
  72. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  73. package/dist/solution/BookingTicket/utils/scan/handleScan.js +10 -2
  74. package/dist/solution/ScanOrder/index.d.ts +26 -14
  75. package/dist/solution/ScanOrder/index.js +1142 -739
  76. package/dist/solution/ScanOrder/types.d.ts +21 -1
  77. package/dist/solution/ScanOrder/utils.d.ts +8 -0
  78. package/dist/solution/ScanOrder/utils.js +97 -45
  79. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  80. package/dist/solution/ShopDiscount/index.js +125 -87
  81. package/dist/solution/UnifiedBookingSales/index.d.ts +204 -0
  82. package/dist/solution/UnifiedBookingSales/index.js +2211 -0
  83. package/dist/solution/UnifiedBookingSales/types.d.ts +150 -0
  84. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  85. package/dist/solution/VenueBooking/index.d.ts +39 -11
  86. package/dist/solution/VenueBooking/index.js +1167 -841
  87. package/dist/solution/VenueBooking/types.d.ts +3 -0
  88. package/dist/solution/VenueBooking/utils/resource.js +1 -0
  89. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  90. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -5
  91. package/dist/solution/index.d.ts +1 -0
  92. package/dist/solution/index.js +2 -1
  93. package/dist/types/index.d.ts +1 -0
  94. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  95. package/lib/modules/BaseModule.d.ts +1 -0
  96. package/lib/modules/BaseModule.js +24 -37
  97. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  98. package/lib/modules/BookingContext/utils/productExtend.js +4 -3
  99. package/lib/modules/BookingContext/utils/timeSlices.js +18 -3
  100. package/lib/modules/Customer/index.d.ts +4 -0
  101. package/lib/modules/Customer/index.js +11 -0
  102. package/lib/modules/Customer/types.d.ts +2 -0
  103. package/lib/modules/Discount/index.d.ts +1 -0
  104. package/lib/modules/Discount/index.js +9 -0
  105. package/lib/modules/Discount/types.d.ts +1 -0
  106. package/lib/modules/Holder/index.d.ts +48 -0
  107. package/lib/modules/Holder/index.js +402 -0
  108. package/lib/modules/Holder/types.d.ts +123 -0
  109. package/lib/modules/Holder/types.js +17 -0
  110. package/lib/modules/Holder/utils.d.ts +13 -0
  111. package/lib/modules/Holder/utils.js +71 -0
  112. package/lib/modules/OpenData/index.js +1 -1
  113. package/lib/modules/Order/index.d.ts +32 -4
  114. package/lib/modules/Order/index.js +372 -156
  115. package/lib/modules/Order/types.d.ts +22 -1
  116. package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  117. package/lib/modules/Order/utils/discountProductLineIdentity.js +170 -0
  118. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  119. package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
  120. package/lib/modules/Order/utils.d.ts +10 -0
  121. package/lib/modules/Order/utils.js +39 -6
  122. package/lib/modules/Payment/index.d.ts +4 -0
  123. package/lib/modules/Payment/index.js +7 -0
  124. package/lib/modules/Payment/walletpass.js +12 -0
  125. package/lib/modules/Product/types.d.ts +1 -0
  126. package/lib/modules/ProductList/index.js +49 -31
  127. package/lib/modules/Quotation/index.d.ts +1 -1
  128. package/lib/modules/Quotation/index.js +2 -2
  129. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  130. package/lib/modules/ResourcePlanner/index.js +148 -0
  131. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  132. package/lib/modules/ResourcePlanner/planner.js +933 -0
  133. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  134. package/lib/modules/ResourcePlanner/types.js +17 -0
  135. package/lib/modules/Rules/index.js +117 -25
  136. package/lib/modules/SalesSummary/index.js +6 -7
  137. package/lib/modules/ScanOrderLogger/index.d.ts +2 -0
  138. package/lib/modules/ScanOrderLogger/index.js +13 -1
  139. package/lib/modules/ScanOrderLogger/providers/feishu.js +15 -6
  140. package/lib/modules/ScanOrderLogger/types.d.ts +1 -0
  141. package/lib/modules/Schedule/index.d.ts +3 -1
  142. package/lib/modules/Schedule/index.js +10 -8
  143. package/lib/modules/Summary/utils.js +21 -1
  144. package/lib/modules/index.d.ts +2 -0
  145. package/lib/modules/index.js +5 -1
  146. package/lib/plugins/window.d.ts +1 -0
  147. package/lib/server/index.d.ts +20 -0
  148. package/lib/server/index.js +124 -19
  149. package/lib/server/modules/order/index.d.ts +2 -0
  150. package/lib/server/modules/order/index.js +75 -5
  151. package/lib/server/modules/order/types.d.ts +1 -1
  152. package/lib/solution/BaseSales/index.d.ts +20 -1
  153. package/lib/solution/BaseSales/index.js +105 -31
  154. package/lib/solution/BaseSales/utils/cartPromotion.js +18 -0
  155. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -0
  156. package/lib/solution/BaseSales/utils.js +29 -18
  157. package/lib/solution/BookingByStep/index.d.ts +17 -2
  158. package/lib/solution/BookingByStep/index.js +60 -18
  159. package/lib/solution/BookingByStep/types.d.ts +2 -1
  160. package/lib/solution/BookingByStep/types.js +5 -0
  161. package/lib/solution/BookingByStep/utils/capacity.js +20 -1
  162. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  163. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  164. package/lib/solution/BookingTicket/index.d.ts +21 -3
  165. package/lib/solution/BookingTicket/index.js +75 -16
  166. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  167. package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -2
  168. package/lib/solution/ScanOrder/index.d.ts +26 -14
  169. package/lib/solution/ScanOrder/index.js +449 -182
  170. package/lib/solution/ScanOrder/types.d.ts +21 -1
  171. package/lib/solution/ScanOrder/utils.d.ts +8 -0
  172. package/lib/solution/ScanOrder/utils.js +60 -18
  173. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  174. package/lib/solution/ShopDiscount/index.js +14 -0
  175. package/lib/solution/UnifiedBookingSales/index.d.ts +204 -0
  176. package/lib/solution/UnifiedBookingSales/index.js +1273 -0
  177. package/lib/solution/UnifiedBookingSales/types.d.ts +150 -0
  178. package/lib/solution/UnifiedBookingSales/types.js +33 -0
  179. package/lib/solution/VenueBooking/index.d.ts +39 -11
  180. package/lib/solution/VenueBooking/index.js +322 -110
  181. package/lib/solution/VenueBooking/types.d.ts +3 -0
  182. package/lib/solution/VenueBooking/utils/resource.js +1 -0
  183. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  184. package/lib/solution/VenueBooking/utils/slotMerge.js +6 -4
  185. package/lib/solution/index.d.ts +1 -0
  186. package/lib/solution/index.js +3 -1
  187. package/lib/types/index.d.ts +1 -0
  188. package/package.json +1 -1
@@ -35,6 +35,7 @@ export interface ScanOrderOrderProductIdentity {
35
35
  /** 参与合并/匹配;与 remove 通配语义见 isSkuOnlyDeleteIdentity */
36
36
  product_sku?: ScanOrderProductSku;
37
37
  product_bundle?: any[];
38
+ shop_id?: number | string;
38
39
  }
39
40
  export interface ScanOrderProductSku {
40
41
  option: any[];
@@ -207,7 +208,7 @@ export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platfo
207
208
  }>;
208
209
  products: ScanOrderSubmitProduct[];
209
210
  }
210
- export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
211
+ export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'multiple_orders' | 'additional_order_with_code' | 'additional_order';
211
212
  export interface ScanOrderTableFormRecord {
212
213
  policy?: string | null;
213
214
  partyroom_booking?: string | null;
@@ -250,6 +251,10 @@ export interface ScanOrderResourceOccupyDetail {
250
251
  form_id?: number | string | null;
251
252
  order_id?: number | string | null;
252
253
  last_order_id?: number | string | null;
254
+ order_list?: Array<{
255
+ id?: number | string | null;
256
+ [key: string]: any;
257
+ }> | null;
253
258
  resource_capacity?: ScanOrderResourceCapacity[] | null;
254
259
  form_record?: ScanOrderTableFormRecord | null;
255
260
  [key: string]: any;
@@ -263,6 +268,21 @@ export interface ScanOrderResourceOccupyDetailApiResponse {
263
268
  } | null;
264
269
  }
265
270
  export type ScanOrderResourceSelectType = 'single' | 'multiple' | 'capacity';
271
+ export interface ScanOrderReservationResourceSelectInfo {
272
+ resourceSelectType?: ScanOrderResourceSelectType;
273
+ isSingleReservation: boolean;
274
+ isMultipleReservation: boolean;
275
+ isCapacityReservation: boolean;
276
+ }
277
+ export interface ScanOrderAllowAddItemsInfo {
278
+ enabled: boolean;
279
+ }
280
+ export type ScanOrderSyncAdditionalOrderReason = 'missing_resource_id' | 'no_order' | 'multiple_orders' | 'add_items_disabled' | 'invalid_order_id';
281
+ export interface ScanOrderSyncAdditionalOrderResult {
282
+ matched: boolean;
283
+ order_id?: string;
284
+ reason?: ScanOrderSyncAdditionalOrderReason;
285
+ }
266
286
  export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
267
287
  relationId?: string;
268
288
  tableFormId?: string;
@@ -2,6 +2,7 @@ import { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderResource
2
2
  import type { CartItemSummary, ItemRuleBusinessData, PaxInfo, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
3
3
  import type { StrategyConfig } from '../../model/strategy/type';
4
4
  import type { ProductData } from '../../modules/Product/types';
5
+ import type { OrderSubmitProduct } from '../../modules/Order/types';
5
6
  /**
6
7
  * 构建金额全为 0 的空 summary。
7
8
  * 作为尚未计算金额时的兜底默认值,避免下游因 undefined 报错。
@@ -42,6 +43,8 @@ export declare function toNonNegativeNumber(value: unknown): number;
42
43
  export declare function toNonNegativeInt(value: unknown): number;
43
44
  export declare function toPriceString(value: unknown, fallback?: string): string;
44
45
  export declare function buildProductKey(productId: number, productVariantId: number): string;
46
+ /** 加餐接口只提交本次新增商品,过滤掉首单预约占位规则行。 */
47
+ export declare function filterProductsForScanOrderMore<T extends OrderSubmitProduct>(products?: T[]): T[];
45
48
  export declare function getTopLevelProductId(product: Record<string, any>): number | null;
46
49
  export declare function getTopLevelVariantId(product: Record<string, any>): number | null;
47
50
  export declare function buildQuantityLimitIndex(limits: QuantityLimitResult[]): {
@@ -134,6 +137,11 @@ export declare function normalizeOrderProduct(product: Partial<ScanOrderOrderPro
134
137
  * 从 reservation.enabled_reservation_rules 中收集 type=link 的商品 id。
135
138
  */
136
139
  export declare function collectLinkProductIdsFromReservationRules(rules: unknown): number[];
140
+ /**
141
+ * 找到第一个归属指定桌台的预约规则商品。
142
+ * 归属判断基于商品资源中的 default_resource / optional_resource。
143
+ */
144
+ export declare function findReservationRuleProductByResourceId(products: ProductData[], resourceId: string | number | null | undefined): ProductData | undefined;
137
145
  /**
138
146
  * 返回列表中第一个带有效 duration.value(分钟)的商品时长。
139
147
  */
@@ -39,6 +39,8 @@ __export(utils_exports, {
39
39
  computeResourceIsFull: () => computeResourceIsFull,
40
40
  createEmptySummary: () => createEmptySummary,
41
41
  extractStrategyModelIdsFromTableConfig: () => extractStrategyModelIdsFromTableConfig,
42
+ filterProductsForScanOrderMore: () => filterProductsForScanOrderMore,
43
+ findReservationRuleProductByResourceId: () => findReservationRuleProductByResourceId,
42
44
  getProductIdentityIndex: () => getProductIdentityIndex,
43
45
  getSafeProductNum: () => getSafeProductNum,
44
46
  getTopLevelProductId: () => getTopLevelProductId,
@@ -165,6 +167,12 @@ function toPriceString(value, fallback = "0.00") {
165
167
  function buildProductKey(productId, productVariantId) {
166
168
  return `${productId}_${productVariantId}`;
167
169
  }
170
+ function filterProductsForScanOrderMore(products = []) {
171
+ return products.filter((product) => {
172
+ var _a;
173
+ return ((_a = product.metadata) == null ? void 0 : _a.is_rule) !== true;
174
+ });
175
+ }
168
176
  function getTopLevelProductId(product) {
169
177
  const rawProductId = product.product_id ?? product.id;
170
178
  const productId = Number(rawProductId);
@@ -349,33 +357,44 @@ function attachItemRuleLimitsToTopLevelProducts(productList, limits) {
349
357
  return productList;
350
358
  }
351
359
  function buildProductLineFingerprint(productOptionItem, productBundle) {
352
- const optArr = Array.isArray(productOptionItem) ? productOptionItem : [];
353
- const normalizedOpts = optArr.map((item) => ({
354
- option_group_item_id: Number(item == null ? void 0 : item.option_group_item_id) || 0,
355
- option_group_id: Number(item == null ? void 0 : item.option_group_id) || 0,
356
- num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
357
- price: String((item == null ? void 0 : item.add_price) ?? (item == null ? void 0 : item.price) ?? "")
358
- })).sort((p, q) => {
359
- if (p.option_group_item_id !== q.option_group_item_id) {
360
- return p.option_group_item_id - q.option_group_item_id;
361
- }
362
- if (p.option_group_id !== q.option_group_id)
363
- return p.option_group_id - q.option_group_id;
364
- if (p.num !== q.num)
365
- return p.num - q.num;
366
- return p.price.localeCompare(q.price);
367
- });
360
+ const normalizeOptions = (options) => {
361
+ const optionArr = Array.isArray(options) ? options : [];
362
+ return optionArr.map((item) => ({
363
+ option_group_item_id: Number(item == null ? void 0 : item.option_group_item_id) || 0,
364
+ option_group_id: Number(item == null ? void 0 : item.option_group_id) || 0,
365
+ num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
366
+ price: String((item == null ? void 0 : item.add_price) ?? (item == null ? void 0 : item.price) ?? "")
367
+ })).sort((p, q) => {
368
+ if (p.option_group_item_id !== q.option_group_item_id) {
369
+ return p.option_group_item_id - q.option_group_item_id;
370
+ }
371
+ if (p.option_group_id !== q.option_group_id) {
372
+ return p.option_group_id - q.option_group_id;
373
+ }
374
+ if (p.num !== q.num)
375
+ return p.num - q.num;
376
+ return p.price.localeCompare(q.price);
377
+ });
378
+ };
379
+ const normalizedOpts = normalizeOptions(productOptionItem);
368
380
  const bundleArr = Array.isArray(productBundle) ? productBundle : [];
369
381
  const normalizedBundles = bundleArr.map((item) => ({
370
382
  bundle_id: Number((item == null ? void 0 : item.bundle_id) ?? (item == null ? void 0 : item.id) ?? 0) || 0,
371
383
  product_id: Number(item == null ? void 0 : item.product_id) || 0,
372
- num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1
384
+ product_variant_id: Number((item == null ? void 0 : item.bundle_variant_id) ?? (item == null ? void 0 : item.product_variant_id)) || 0,
385
+ num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
386
+ option: normalizeOptions(item == null ? void 0 : item.option)
373
387
  })).sort((p, q) => {
374
388
  if (p.bundle_id !== q.bundle_id)
375
389
  return p.bundle_id - q.bundle_id;
376
390
  if (p.product_id !== q.product_id)
377
391
  return p.product_id - q.product_id;
378
- return p.num - q.num;
392
+ if (p.product_variant_id !== q.product_variant_id) {
393
+ return p.product_variant_id - q.product_variant_id;
394
+ }
395
+ if (p.num !== q.num)
396
+ return p.num - q.num;
397
+ return JSON.stringify(p.option).localeCompare(JSON.stringify(q.option));
379
398
  });
380
399
  return JSON.stringify([normalizedOpts, normalizedBundles]);
381
400
  }
@@ -580,6 +599,27 @@ function collectLinkProductIdsFromReservationRules(rules) {
580
599
  }
581
600
  return [...new Set(ids)];
582
601
  }
602
+ function findReservationRuleProductByResourceId(products, resourceId) {
603
+ var _a;
604
+ const numericResourceId = Number(resourceId);
605
+ if (!Number.isFinite(numericResourceId) || numericResourceId <= 0)
606
+ return void 0;
607
+ for (const product of products) {
608
+ const resources = (_a = product == null ? void 0 : product.product_resource) == null ? void 0 : _a.resources;
609
+ if (!Array.isArray(resources))
610
+ continue;
611
+ const hasMatchedResource = resources.some((resource) => {
612
+ const defaultResources = Array.isArray(resource == null ? void 0 : resource.default_resource) ? resource.default_resource : [];
613
+ const optionalResources = Array.isArray(resource == null ? void 0 : resource.optional_resource) ? resource.optional_resource : [];
614
+ return [...defaultResources, ...optionalResources].some(
615
+ (id) => Number(id) === numericResourceId
616
+ );
617
+ });
618
+ if (hasMatchedResource)
619
+ return product;
620
+ }
621
+ return void 0;
622
+ }
583
623
  function pickFirstDurationMinutesFromProducts(products) {
584
624
  var _a;
585
625
  for (const product of products) {
@@ -683,6 +723,8 @@ function pickFirstCustomCapacityDimensionId(products) {
683
723
  computeResourceIsFull,
684
724
  createEmptySummary,
685
725
  extractStrategyModelIdsFromTableConfig,
726
+ filterProductsForScanOrderMore,
727
+ findReservationRuleProductByResourceId,
686
728
  getProductIdentityIndex,
687
729
  getSafeProductNum,
688
730
  getTopLevelProductId,
@@ -40,6 +40,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
40
40
  discountList: Discount[];
41
41
  };
42
42
  setProductList(productList: Record<string, any>[]): void;
43
+ batchSearchByProductIds(productIds: number[]): Promise<Discount[]>;
43
44
  scanCode(code: string, customerId?: number): Promise<{
44
45
  isAvailable: boolean;
45
46
  productList: Record<string, any>[];
@@ -270,6 +270,20 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
270
270
  setProductList(productList) {
271
271
  this.store.productList = productList;
272
272
  }
273
+ async batchSearchByProductIds(productIds) {
274
+ var _a;
275
+ let resultDiscountList = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearchByProductIds(productIds)) || [];
276
+ resultDiscountList = resultDiscountList.map((item) => {
277
+ return {
278
+ ...item,
279
+ discount_rule_uncheck_flag: true
280
+ };
281
+ });
282
+ const currentDiscountList = this.getDiscountList() || [];
283
+ const newDiscountList = [...currentDiscountList, ...resultDiscountList];
284
+ this.setDiscountList(newDiscountList);
285
+ return newDiscountList;
286
+ }
273
287
  // 扫码输入code
274
288
  async scanCode(code, customerId) {
275
289
  var _a, _b, _c;
@@ -0,0 +1,204 @@
1
+ import type { Module } from '../../types';
2
+ import type { ProductData } from '../../modules';
3
+ import type { OpenDataConfig } from '../../modules/OpenData';
4
+ import type { LoadScheduleAvailableDateParams, ScheduleItem } from '../../modules/Schedule/types';
5
+ import type { ProductListLoadProductsParams } from '../../modules/ProductList';
6
+ import type { ResourcePlannerAssignment, ResourcePlannerAssignableSlotResult, ResourcePlannerEvent, ResourcePlannerProduct, ResourcePlannerProjection, ResourcePlannerQuery, ResourcePlannerResource, ResourcePlannerSelectionPatch, ResourcePlannerSnapshot, ResourcePlannerValidationResult } from '../../modules/ResourcePlanner';
7
+ import type { UnifiedBookingSalesCommitPlannerSelectionParams, UnifiedBookingSalesCommitResult, UnifiedBookingSalesAddRetailProductParams, UnifiedBookingSalesApplyPlannerDiscountsParams, UnifiedBookingSalesDiscountResult, UnifiedBookingSalesLoadProductsByScheduleDateParams, UnifiedBookingSalesLoadPlannerContextParams, UnifiedBookingSalesLoadOpenDataParams, UnifiedBookingSalesStagePlannerProductsParams, UnifiedBookingSalesStageRetailProductsParams, UnifiedBookingSalesState } from './types';
8
+ import { BookingTicket } from '../BookingTicket';
9
+ export * from './types';
10
+ /**
11
+ * Converts Rules/Order discount internals into a small UI-facing diagnostic. The result keeps
12
+ * candidate-card state separate from line-level applications: a selected card is not proof that
13
+ * it actually discounted a planner product.
14
+ */
15
+ export declare function buildPlannerDiscountResult(params: {
16
+ customerId: number | null;
17
+ discountList: Record<string, any>[];
18
+ products: Record<string, any>[];
19
+ summaryBefore?: unknown;
20
+ summaryAfter?: unknown;
21
+ status: UnifiedBookingSalesDiscountResult['status'];
22
+ preferredDiscountId?: number | string;
23
+ preferredDiscountFound?: boolean;
24
+ }): UnifiedBookingSalesDiscountResult;
25
+ /** Converts a ProductList record into the pure input shape consumed by ResourcePlanner. */
26
+ export declare function normalizeProductForPlanner(product: ProductData | Record<string, any>): ResourcePlannerProduct;
27
+ /**
28
+ * Materializes resource work windows locally from v2's schedule ids, then keeps its flat
29
+ * event_list as planner events. This deliberately avoids the older API's times -> event_list
30
+ * response nesting and lets one resource response serve any requested date range.
31
+ */
32
+ export declare function buildPlannerResourcesFromV2(params: {
33
+ rawResources: Record<string, any>[];
34
+ scheduleList: ScheduleItem[];
35
+ dateRange?: ResourcePlannerQuery['dateRange'];
36
+ }): {
37
+ resources: ResourcePlannerResource[];
38
+ externalEvents: ResourcePlannerEvent[];
39
+ };
40
+ /** Combines URL-locked resources with every resource referenced by the selected products. */
41
+ export declare function collectPlannerResourceIds(products: ResourcePlannerProduct[], explicitResourceIds?: Array<number | string>): Array<number | string>;
42
+ /** Convenience wrapper for the usual one-resource booking case. */
43
+ export declare function buildBookingFromAssignment(params: {
44
+ assignment: ResourcePlannerAssignment;
45
+ product: ResourcePlannerProduct;
46
+ }): Record<string, any>;
47
+ /**
48
+ * Converts all resources needed by one product/time interval into the one booking expected by
49
+ * OrderModule. Callers must group assignments before this function so a multi-form booking does
50
+ * not become several competing bookings.
51
+ */
52
+ export declare function buildBookingFromAssignments(params: {
53
+ assignments: ResourcePlannerAssignment[];
54
+ product: ResourcePlannerProduct;
55
+ }): Record<string, any>;
56
+ /** Builds the exact identity BaseSales needs to remove only this solution's order lines. */
57
+ export declare function buildPlannerLineIdentity(product: Record<string, any>): Record<string, any>;
58
+ export declare class UnifiedBookingSalesImpl extends BookingTicket {
59
+ protected defaultName: string;
60
+ protected defaultVersion: string;
61
+ protected store: UnifiedBookingSalesState;
62
+ private unifiedProductCatalog;
63
+ private openDataTarget;
64
+ private loadOpenDataInFlight;
65
+ private loadOpenDataInFlightTarget;
66
+ protected getSubmitOrderSalesChannel(): string;
67
+ protected isSessionStoragePersistEnabled(): boolean;
68
+ protected shouldUseSessionStorageForSubModule(moduleName?: string): boolean;
69
+ /**
70
+ * 读取与当前 cacheId 同分桶的 Solution 会话状态。
71
+ * 该状态独立于 otherParams,适合页面皮肤保存短生命周期 UI 状态。
72
+ */
73
+ getSessionStateValue<T = unknown>(key: string): T | undefined;
74
+ /**
75
+ * 写入与当前 cacheId 同分桶的 Solution 会话状态。
76
+ * value 为 undefined 时删除该 key;存储失败不阻断业务流程。
77
+ */
78
+ setSessionStateValue(key: string, value: unknown): void;
79
+ /**
80
+ * 清除当前 cacheId 的可恢复订单快照,同时保留 Solution UI sessionState。
81
+ * 用于支付跳转等终态场景,避免浏览器返回时恢复已提交订单。
82
+ */
83
+ clearSessionStorageOrderSnapshot(): void;
84
+ /**
85
+ * Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
86
+ * 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
87
+ */
88
+ protected shouldUseCheckoutSyncTask(): boolean;
89
+ /** UnifiedBookingSales 的真实结账默认请求收据数据,供云端确认后再本地打印。 */
90
+ protected getDefaultCheckoutSmallTicketDataFlag(): number;
91
+ protected getRegisteredModuleNames(): readonly string[];
92
+ protected createSubModule(moduleName: string): Module | null;
93
+ addNewOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
94
+ syncAuthenticatedOrderCustomer(): Promise<boolean>;
95
+ private isAuthenticatedCustomerUserPlatform;
96
+ private resolveDiscountOrderIdentity;
97
+ private resolveDiscountAction;
98
+ private resetCachedCustomerDiscountState;
99
+ private refreshLegacySessionCustomerDiscounts;
100
+ /**
101
+ * Loads OpenData without borrowing BookingTicket. Cache ownership is tied to the exact
102
+ * business/channel target so a reused solution instance cannot leak another entry's menus.
103
+ */
104
+ loadOpenData(params: UnifiedBookingSalesLoadOpenDataParams): Promise<OpenDataConfig>;
105
+ getOpenData(): Promise<OpenDataConfig | null>;
106
+ /**
107
+ * Loads the product catalog used by both UI and Planner. Schedule data is requested with each
108
+ * product because session products carry their fixed intervals there.
109
+ */
110
+ loadProducts(params?: ProductListLoadProductsParams, options?: {
111
+ callback?: (result: any) => void;
112
+ subscriberId?: string;
113
+ }): Promise<ProductData[]>;
114
+ /** Date-first entry point. It delegates protocol details and cache ownership to ScheduleModule. */
115
+ loadScheduleAvailableDate(params: LoadScheduleAvailableDateParams): Promise<import("../../modules/Date/types").ITime[]>;
116
+ /**
117
+ * Implements the date-first product pool: the chosen date's product ids plus globally sellable
118
+ * other_product_ids. If a batch product query is unexpectedly empty, retry one id at a time so
119
+ * a partial backend incompatibility does not hide the entire date's catalog.
120
+ */
121
+ loadProductsByScheduleDate(params: UnifiedBookingSalesLoadProductsByScheduleDateParams): Promise<ProductData[]>;
122
+ /** Returns a copy so UI consumers cannot accidentally mutate the solution's product cache. */
123
+ getProductCatalog(): {
124
+ products: ProductData[];
125
+ };
126
+ /**
127
+ * Read-only compatibility view for salesSdk skins. It reconnects a booking to its product but
128
+ * must not be used to mutate tempOrder; all writes go through BaseSales / planner APIs.
129
+ */
130
+ /**
131
+ * Loads the current customer's product coupons and discount cards after planner lines exist,
132
+ * then optionally lets the existing Rules engine select the best valid combination. This is a
133
+ * diagnostic boundary for new booking skins: no pricing logic is duplicated in the planner.
134
+ */
135
+ applyPlannerDiscounts(params?: UnifiedBookingSalesApplyPlannerDiscountsParams): Promise<UnifiedBookingSalesDiscountResult>;
136
+ /** ResourcePlanner is a required child module; fail early instead of producing partial availability. */
137
+ private getPlanner;
138
+ private buildUnifiedOrderProduct;
139
+ /** Replacing a staged selection is idempotent and never removes unrelated cart lines. */
140
+ private removeExistingStagedLines;
141
+ private stageProducts;
142
+ /**
143
+ * Adds the current product choice to an otherwise clean planner cart without creating bookings.
144
+ * This separates "what the customer wants" from the later time/resource confirmation step.
145
+ */
146
+ stagePlannerProducts(params: UnifiedBookingSalesStagePlannerProductsParams): Promise<Record<string, any> | null>;
147
+ /**
148
+ * Adds ordinary retail products without asking ResourcePlanner for booking facts.
149
+ * Its staged lines have separate ownership so planner and retail skins can coexist safely.
150
+ */
151
+ stageRetailProducts(params: UnifiedBookingSalesStageRetailProductsParams): Promise<Record<string, any> | null>;
152
+ /**
153
+ * Adds one retail line without replacing the cart's existing retail selection.
154
+ * This is intentionally separate from stageRetailProducts(), whose contract is
155
+ * "replace the staged selection" for demo and wizard-like callers.
156
+ */
157
+ addRetailProduct(params: UnifiedBookingSalesAddRetailProductParams): Promise<Record<string, any>[]>;
158
+ /** Normalizes caller-provided products or loads the catalog before any resource request is made. */
159
+ private loadPlannerProducts;
160
+ /** Loads the reusable store-level schedule catalog on demand. */
161
+ private ensurePlannerSchedulesLoaded;
162
+ /**
163
+ * v2 resources reference schedule ids rather than expanded work times. Refresh once when the
164
+ * cached schedule catalog cannot materialize all referenced ids.
165
+ */
166
+ private ensurePlannerSchedulesForResources;
167
+ /**
168
+ * Fetches resource metadata plus flat occupied events. Work windows are intentionally derived
169
+ * locally in buildPlannerResourcesFromV2 from /schedule, rather than requested from the legacy
170
+ * resource dates endpoint.
171
+ */
172
+ private fetchPlannerResourcesV2;
173
+ /**
174
+ * Resolves the Planner context in precedence order: explicit normalized context, test raw data,
175
+ * then the v2 resource API inferred from selected product requirements and any URL lock.
176
+ */
177
+ private loadPlannerResources;
178
+ /**
179
+ * Boundary between IO and pure planning. Once this returns, all later availability/slot calls
180
+ * operate on the ResourcePlanner snapshot and do not issue resource requests themselves.
181
+ */
182
+ loadPlannerContext(params?: UnifiedBookingSalesLoadPlannerContextParams): Promise<ResourcePlannerSnapshot>;
183
+ /** Returns cells, date summaries and a derived grid; cells are continuous ranges, not UI slots. */
184
+ queryPlannerAvailability(query?: ResourcePlannerQuery): Promise<ResourcePlannerProjection>;
185
+ /** Turns compatible availability ranges into user-selectable intervals and ready-to-commit assignments. */
186
+ resolveAssignableSlots(query?: ResourcePlannerQuery): ResourcePlannerAssignableSlotResult;
187
+ /** Stores a UI choice only. It is deliberately side-effect free with respect to tempOrder. */
188
+ setPlannerSelection(patch: ResourcePlannerSelectionPatch): ResourcePlannerSnapshot;
189
+ /**
190
+ * Legacy-friendly automatic assignment for already fixed intervals. Duration products without a
191
+ * start time intentionally remain unresolved; callers offering a picker should use slots.
192
+ */
193
+ autoAssignPlanner(query?: ResourcePlannerQuery): Promise<ResourcePlannerSnapshot>;
194
+ /** Rechecks remote events, capacity and conflicts among the current selection before committing. */
195
+ validatePlannerSelection(): ResourcePlannerValidationResult;
196
+ /** Read-only snapshot for UI diagnostics and progressive flow steps. */
197
+ getPlannerSnapshot(): ResourcePlannerSnapshot;
198
+ /**
199
+ * Validates then writes assignments to tempOrder. Real order submission is opt-in so UI callers
200
+ * can safely preview the cart; pass submitAfterCommit only after an explicit confirmation.
201
+ */
202
+ commitPlannerSelection(params?: UnifiedBookingSalesCommitPlannerSelectionParams): Promise<UnifiedBookingSalesCommitResult>;
203
+ }
204
+ export declare const UnifiedBookingSales: typeof UnifiedBookingSalesImpl;