@pisell/pisellos 0.0.571 → 0.0.572

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 (143) hide show
  1. package/dist/effects/index.d.ts +2 -2
  2. package/dist/model/strategy/adapter/dataVariant/type.d.ts +3 -3
  3. package/dist/model/strategy/adapter/itemRule/type.d.ts +6 -6
  4. package/dist/model/strategy/adapter/promotion/index.d.ts +4 -0
  5. package/dist/model/strategy/adapter/promotion/type.d.ts +5 -5
  6. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  7. package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
  8. package/dist/model/strategy/type.d.ts +1 -1
  9. package/dist/modules/BookingContext/types.d.ts +4 -4
  10. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +1 -1
  11. package/dist/modules/Customer/types.d.ts +1 -1
  12. package/dist/modules/Discount/availability.d.ts +7 -0
  13. package/dist/modules/Discount/availability.js +52 -0
  14. package/dist/modules/Discount/entitlementPass.d.ts +34 -0
  15. package/dist/modules/Discount/entitlementPass.js +147 -0
  16. package/dist/modules/Discount/entitlementState.d.ts +8 -0
  17. package/dist/modules/Discount/entitlementState.js +205 -0
  18. package/dist/modules/Discount/index.d.ts +5 -2
  19. package/dist/modules/Discount/index.js +124 -25
  20. package/dist/modules/Discount/types.d.ts +29 -6
  21. package/dist/modules/Holder/types.d.ts +1 -1
  22. package/dist/modules/OpenData/types.d.ts +1 -1
  23. package/dist/modules/Order/types.d.ts +5 -5
  24. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +1 -1
  25. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +1 -1
  26. package/dist/modules/Order/utils.d.ts +1 -1
  27. package/dist/modules/Payment/types.d.ts +7 -7
  28. package/dist/modules/Product/index.d.ts +1 -1
  29. package/dist/modules/ResourcePlanner/types.d.ts +4 -4
  30. package/dist/modules/Rules/entitlementLines.d.ts +8 -0
  31. package/dist/modules/Rules/entitlementLines.js +159 -0
  32. package/dist/modules/Rules/index.d.ts +13 -3
  33. package/dist/modules/Rules/index.js +617 -342
  34. package/dist/modules/Rules/types.d.ts +4 -4
  35. package/dist/modules/ScanOrderLogger/types.d.ts +2 -2
  36. package/dist/modules/Schedule/getDateIsInSchedule.d.ts +1 -1
  37. package/dist/modules/Schedule/type.d.ts +7 -7
  38. package/dist/modules/Schedule/types.d.ts +9 -9
  39. package/dist/plugins/app.d.ts +1 -1
  40. package/dist/plugins/request.d.ts +2 -2
  41. package/dist/plugins/window.d.ts +2 -2
  42. package/dist/server/modules/floor-plan/types.d.ts +1 -1
  43. package/dist/server/modules/menu/types.d.ts +1 -1
  44. package/dist/server/modules/order/types.d.ts +16 -16
  45. package/dist/server/modules/products/types.d.ts +1 -1
  46. package/dist/server/modules/resource/types.d.ts +1 -1
  47. package/dist/server/modules/schedule/utils.d.ts +1 -1
  48. package/dist/server/types.d.ts +4 -4
  49. package/dist/server/utils/small-ticket.d.ts +1 -1
  50. package/dist/solution/BaseSales/index.d.ts +1 -1
  51. package/dist/solution/BaseSales/types.d.ts +7 -7
  52. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -1
  53. package/dist/solution/BookingByStep/index.d.ts +1 -1
  54. package/dist/solution/BookingByStep/utils/resources.d.ts +1 -1
  55. package/dist/solution/BookingTicket/index.d.ts +13 -1
  56. package/dist/solution/BookingTicket/types.d.ts +3 -3
  57. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
  58. package/dist/solution/BookingTicket/utils/bookingStatus.d.ts +1 -1
  59. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +1 -1
  60. package/dist/solution/Sales/types.d.ts +4 -4
  61. package/dist/solution/ScanOrder/types.d.ts +5 -5
  62. package/dist/solution/ShopDiscount/index.d.ts +3 -0
  63. package/dist/solution/ShopDiscount/index.js +161 -78
  64. package/dist/solution/ShopDiscount/types.d.ts +1 -1
  65. package/dist/solution/ShopDiscount/utils.d.ts +3 -2
  66. package/dist/solution/ShopDiscount/utils.js +40 -1
  67. package/dist/solution/UnifiedBookingSales/types.d.ts +1 -1
  68. package/dist/solution/VenueBooking/types.d.ts +1 -1
  69. package/dist/types/index.d.ts +1 -1
  70. package/dist/utils/task.d.ts +2 -2
  71. package/dist/utils/watch.d.ts +2 -2
  72. package/lib/effects/index.d.ts +2 -2
  73. package/lib/model/strategy/adapter/dataVariant/type.d.ts +3 -3
  74. package/lib/model/strategy/adapter/itemRule/type.d.ts +6 -6
  75. package/lib/model/strategy/adapter/promotion/index.d.ts +4 -0
  76. package/lib/model/strategy/adapter/promotion/type.d.ts +5 -5
  77. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  78. package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
  79. package/lib/model/strategy/type.d.ts +1 -1
  80. package/lib/modules/BookingContext/types.d.ts +4 -4
  81. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +1 -1
  82. package/lib/modules/Customer/types.d.ts +1 -1
  83. package/lib/modules/Discount/availability.d.ts +7 -0
  84. package/lib/modules/Discount/availability.js +46 -0
  85. package/lib/modules/Discount/entitlementPass.d.ts +34 -0
  86. package/lib/modules/Discount/entitlementPass.js +141 -0
  87. package/lib/modules/Discount/entitlementState.d.ts +8 -0
  88. package/lib/modules/Discount/entitlementState.js +150 -0
  89. package/lib/modules/Discount/index.d.ts +5 -2
  90. package/lib/modules/Discount/index.js +59 -14
  91. package/lib/modules/Discount/types.d.ts +29 -6
  92. package/lib/modules/Holder/types.d.ts +1 -1
  93. package/lib/modules/OpenData/types.d.ts +1 -1
  94. package/lib/modules/Order/types.d.ts +5 -5
  95. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +1 -1
  96. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +1 -1
  97. package/lib/modules/Order/utils.d.ts +1 -1
  98. package/lib/modules/Payment/types.d.ts +7 -7
  99. package/lib/modules/Product/index.d.ts +1 -1
  100. package/lib/modules/ResourcePlanner/types.d.ts +4 -4
  101. package/lib/modules/Rules/entitlementLines.d.ts +8 -0
  102. package/lib/modules/Rules/entitlementLines.js +128 -0
  103. package/lib/modules/Rules/index.d.ts +13 -3
  104. package/lib/modules/Rules/index.js +284 -61
  105. package/lib/modules/Rules/types.d.ts +4 -4
  106. package/lib/modules/ScanOrderLogger/types.d.ts +2 -2
  107. package/lib/modules/Schedule/getDateIsInSchedule.d.ts +1 -1
  108. package/lib/modules/Schedule/type.d.ts +7 -7
  109. package/lib/modules/Schedule/types.d.ts +9 -9
  110. package/lib/plugins/app.d.ts +1 -1
  111. package/lib/plugins/request.d.ts +2 -2
  112. package/lib/plugins/window.d.ts +2 -2
  113. package/lib/server/modules/floor-plan/types.d.ts +1 -1
  114. package/lib/server/modules/menu/types.d.ts +1 -1
  115. package/lib/server/modules/order/types.d.ts +16 -16
  116. package/lib/server/modules/products/types.d.ts +1 -1
  117. package/lib/server/modules/resource/types.d.ts +1 -1
  118. package/lib/server/modules/schedule/utils.d.ts +1 -1
  119. package/lib/server/types.d.ts +4 -4
  120. package/lib/server/utils/small-ticket.d.ts +1 -1
  121. package/lib/solution/BaseSales/index.d.ts +1 -1
  122. package/lib/solution/BaseSales/types.d.ts +7 -7
  123. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -1
  124. package/lib/solution/BookingByStep/index.d.ts +1 -1
  125. package/lib/solution/BookingByStep/utils/resources.d.ts +1 -1
  126. package/lib/solution/BookingTicket/index.d.ts +13 -1
  127. package/lib/solution/BookingTicket/types.d.ts +3 -3
  128. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +1 -1
  129. package/lib/solution/BookingTicket/utils/bookingStatus.d.ts +1 -1
  130. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +1 -1
  131. package/lib/solution/Sales/types.d.ts +4 -4
  132. package/lib/solution/ScanOrder/types.d.ts +5 -5
  133. package/lib/solution/ShopDiscount/index.d.ts +3 -0
  134. package/lib/solution/ShopDiscount/index.js +55 -18
  135. package/lib/solution/ShopDiscount/types.d.ts +1 -1
  136. package/lib/solution/ShopDiscount/utils.d.ts +3 -2
  137. package/lib/solution/ShopDiscount/utils.js +39 -3
  138. package/lib/solution/UnifiedBookingSales/types.d.ts +1 -1
  139. package/lib/solution/VenueBooking/types.d.ts +1 -1
  140. package/lib/types/index.d.ts +1 -1
  141. package/lib/utils/task.d.ts +2 -2
  142. package/lib/utils/watch.d.ts +2 -2
  143. package/package.json +19 -18
@@ -1,8 +1,8 @@
1
- declare type EffectCallback = (payload: any) => void | Promise<void | {
1
+ type EffectCallback = (payload: any) => void | Promise<void | {
2
2
  status: boolean;
3
3
  message?: string;
4
4
  }>;
5
- declare type UnsubscribeFunction = () => void;
5
+ type UnsubscribeFunction = () => void;
6
6
  declare class EffectsManager {
7
7
  private listeners;
8
8
  on(event: string, callback: EffectCallback): UnsubscribeFunction;
@@ -8,7 +8,7 @@ import type { ScheduleItem } from '../../../../modules/Schedule/types';
8
8
  export declare const DATA_VARIANT_ACTION_TYPES: {
9
9
  readonly APPLY: "DATA_VARIANT_APPLY";
10
10
  };
11
- export declare type DataVariantActionType = (typeof DATA_VARIANT_ACTION_TYPES)[keyof typeof DATA_VARIANT_ACTION_TYPES];
11
+ export type DataVariantActionType = (typeof DATA_VARIANT_ACTION_TYPES)[keyof typeof DATA_VARIANT_ACTION_TYPES];
12
12
  /**
13
13
  * Data Variant 规则元数据。
14
14
  *
@@ -116,7 +116,7 @@ export interface EffectiveRuleInfo {
116
116
  productRules: ConditionRule[];
117
117
  globalResult: EvaluationResult;
118
118
  }
119
- export declare type GlobalEffectiveRuleMap = Map<string, EffectiveRuleInfo>;
119
+ export type GlobalEffectiveRuleMap = Map<string, EffectiveRuleInfo>;
120
120
  /**
121
121
  * 单条商品命中的变体覆盖信息。
122
122
  */
@@ -145,4 +145,4 @@ export interface ResolvedDataVariantResult {
145
145
  scheduleTimePoints: string[];
146
146
  rawResults: EvaluationResult[];
147
147
  }
148
- export declare type ConditionScope = 'global' | 'product';
148
+ export type ConditionScope = 'global' | 'product';
@@ -5,7 +5,7 @@ export declare const ITEM_RULE_ACTION_TYPES: {
5
5
  /** 预填购物车 */
6
6
  readonly PREFILL_CART: "PREFILL_CART";
7
7
  };
8
- export declare type ItemRuleActionType = (typeof ITEM_RULE_ACTION_TYPES)[keyof typeof ITEM_RULE_ACTION_TYPES];
8
+ export type ItemRuleActionType = (typeof ITEM_RULE_ACTION_TYPES)[keyof typeof ITEM_RULE_ACTION_TYPES];
9
9
  export declare const ITEM_RULE_TEMPLATES: {
10
10
  /** 空白规则 */
11
11
  readonly BLANK: "blank";
@@ -16,15 +16,15 @@ export declare const ITEM_RULE_TEMPLATES: {
16
16
  /** 必选商品 */
17
17
  readonly MUST_INCLUDE: "must_include";
18
18
  };
19
- export declare type ItemRuleTemplate = (typeof ITEM_RULE_TEMPLATES)[keyof typeof ITEM_RULE_TEMPLATES];
19
+ export type ItemRuleTemplate = (typeof ITEM_RULE_TEMPLATES)[keyof typeof ITEM_RULE_TEMPLATES];
20
20
  /** 数量比较类型 */
21
- export declare type QuantityComparison = 'minimum' | 'maximum' | 'exact' | 'must_include';
21
+ export type QuantityComparison = 'minimum' | 'maximum' | 'exact' | 'must_include';
22
22
  /** 数量来源 */
23
- export declare type QuantitySource = 'total_pax' | 'adult_pax' | 'fixed';
23
+ export type QuantitySource = 'total_pax' | 'adult_pax' | 'fixed';
24
24
  /** 目标类型(当前仅支持按商品) */
25
- export declare type TargetType = 'product';
25
+ export type TargetType = 'product';
26
26
  /** 作用范围 */
27
- export declare type RuleScope = 'each_submission' | 'first_submission_only' | 'subsequent_only' | 'cumulative';
27
+ export type RuleScope = 'each_submission' | 'first_submission_only' | 'subsequent_only' | 'cumulative';
28
28
  /**
29
29
  * 单条数量规则
30
30
  *
@@ -0,0 +1,4 @@
1
+ export { PromotionEvaluator } from './evaluator';
2
+ export { PromotionAdapter } from './adapter';
3
+ export { default } from './adapter';
4
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, } from './examples';
@@ -17,7 +17,7 @@ export declare const PROMOTION_ACTION_TYPES: {
17
17
  /** 固定减价 */
18
18
  readonly DEDUCT_AMOUNT: "DEDUCT_AMOUNT";
19
19
  };
20
- export declare type PromotionActionType = (typeof PROMOTION_ACTION_TYPES)[keyof typeof PROMOTION_ACTION_TYPES];
20
+ export type PromotionActionType = (typeof PROMOTION_ACTION_TYPES)[keyof typeof PROMOTION_ACTION_TYPES];
21
21
  /**
22
22
  * X件Y元 - Action Value
23
23
  *
@@ -54,7 +54,7 @@ export interface BuyXGetYFreeValue {
54
54
  /**
55
55
  * 赠品选择模式
56
56
  */
57
- export declare type GiftSelectionMode = 'user_select' | 'auto' | 'cheapest';
57
+ export type GiftSelectionMode = 'user_select' | 'auto' | 'cheapest';
58
58
  /**
59
59
  * 买X送Y - Action Config
60
60
  */
@@ -105,7 +105,7 @@ export interface BuyXGetYFreeAction extends Omit<ActionEffect, 'type' | 'value'
105
105
  /**
106
106
  * 促销活动 Action 联合类型
107
107
  */
108
- export declare type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction;
108
+ export type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction;
109
109
  /**
110
110
  * 促销相关运算符
111
111
  */
@@ -135,7 +135,7 @@ export interface PromotionBusinessData {
135
135
  /** 自定义属性 */
136
136
  custom?: Record<string, any>;
137
137
  }
138
- declare type ProductBundleItem = {
138
+ type ProductBundleItem = {
139
139
  /** 主商品ID */
140
140
  product_id: number;
141
141
  /** 变体ID(0 表示无变体) */
@@ -195,7 +195,7 @@ export interface PromotionTransformResult {
195
195
  /**
196
196
  * Action 详情联合类型
197
197
  */
198
- export declare type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail;
198
+ export type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail;
199
199
  /**
200
200
  * X件Y元 Action 详情
201
201
  */
@@ -28,6 +28,8 @@ export declare class WalletPassEvaluator {
28
28
  /** 检查代金券/折扣卡是否可用 并返回config */
29
29
  checkVoucherAvailability(input: EvaluatorInput): {
30
30
  isAvailable: boolean;
31
+ reason: string | undefined;
32
+ reasonCode: string | undefined;
31
33
  config: {
32
34
  [x: string]: any;
33
35
  };
@@ -283,7 +283,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
283
283
  }, {
284
284
  key: "checkVoucherAvailability",
285
285
  value: function checkVoucherAvailability(input) {
286
- var _results$, _results$2;
286
+ var _results$, _results$2, _results$3, _results$4;
287
287
  var orderTotalAmount = input.orderTotalAmount,
288
288
  products = input.products,
289
289
  vouchers = input.vouchers;
@@ -291,7 +291,9 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
291
291
  var isAvailable = ((_results$ = results[0]) === null || _results$ === void 0 ? void 0 : _results$.isApplicable) || false;
292
292
  return {
293
293
  isAvailable: isAvailable,
294
- config: _objectSpread({}, (_results$2 = results[0]) === null || _results$2 === void 0 || (_results$2 = _results$2.strategyResult) === null || _results$2 === void 0 || (_results$2 = _results$2.config) === null || _results$2 === void 0 || (_results$2 = _results$2.metadata) === null || _results$2 === void 0 ? void 0 : _results$2.custom)
294
+ reason: (_results$2 = results[0]) === null || _results$2 === void 0 ? void 0 : _results$2.reason,
295
+ reasonCode: (_results$3 = results[0]) === null || _results$3 === void 0 ? void 0 : _results$3.reasonCode,
296
+ config: _objectSpread({}, (_results$4 = results[0]) === null || _results$4 === void 0 || (_results$4 = _results$4.strategyResult) === null || _results$4 === void 0 || (_results$4 = _results$4.config) === null || _results$4 === void 0 || (_results$4 = _results$4.metadata) === null || _results$4 === void 0 ? void 0 : _results$4.custom)
295
297
  };
296
298
  }
297
299
 
@@ -242,4 +242,4 @@ export interface EngineOptions {
242
242
  /**
243
243
  * 运算符处理器
244
244
  */
245
- export declare type OperatorHandler = (fieldValue: any, compareValue: any, rule: ConditionRule) => boolean;
245
+ export type OperatorHandler = (fieldValue: any, compareValue: any, rule: ConditionRule) => boolean;
@@ -39,17 +39,17 @@ export interface InitBookingContextParams {
39
39
  * 资源全集 map:key 为资源 id(数字),value 为资源原始对象,含 times / event_list 等运行态。
40
40
  * 这里只声明 Record 形态;具体字段保留 `any`,与 ticketBooking 现网传入的数据形状兼容。
41
41
  */
42
- export declare type BookingContextResource = Record<string, any>;
43
- export declare type BookingContextResourceMap = Record<string, BookingContextResource>;
42
+ export type BookingContextResource = Record<string, any>;
43
+ export type BookingContextResourceMap = Record<string, BookingContextResource>;
44
44
  /**
45
45
  * 形参 booking_config(结构来自 `/core/board/management/config` 接口)。
46
46
  * OS 不强制 schema,保留 `Record<string, any>` 兼容现网;常用路径文档化在 SDK docs。
47
47
  */
48
- export declare type BookingContextConfig = Record<string, any>;
48
+ export type BookingContextConfig = Record<string, any>;
49
49
  /**
50
50
  * 日期入参:接受 dayjs 实例、ISO 字符串、Date 实例;内部统一 normalize 为 ISO 字符串保存。
51
51
  */
52
- export declare type BookingContextDateInput = string | Date | {
52
+ export type BookingContextDateInput = string | Date | {
53
53
  format?: (fmt?: string) => string;
54
54
  } | null | undefined;
55
55
  /**
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * OS 这边不耦合 i18n 文案,UI 拿到 reason + params 后自行渲染(参考 docs/SDK 中给出的 i18n key 对照表)。
11
11
  */
12
- export declare type ResourceUnavailableReason = 'no_product' | 'time_out_of_range' | 'count_out_of_range' | 'resource_unbound';
12
+ export type ResourceUnavailableReason = 'no_product' | 'time_out_of_range' | 'count_out_of_range' | 'resource_unbound';
13
13
  export interface ResourceError {
14
14
  reason: ResourceUnavailableReason;
15
15
  params: {
@@ -33,7 +33,7 @@ export interface ShopCustomer extends ICustomer {
33
33
  * walletDetails.wallet: 用户所有wallet
34
34
  * latestWalletDetail.wallet: 用户最新wallet
35
35
  */
36
- declare type CustomerWith = 'formRecord' | 'walletDetails.wallet' | 'latestWalletDetail.wallet';
36
+ type CustomerWith = 'formRecord' | 'walletDetails.wallet' | 'latestWalletDetail.wallet';
37
37
  /**
38
38
  * 获取客户列表参数
39
39
  */
@@ -0,0 +1,7 @@
1
+ import type { Discount, DiscountFilterRejectKey } from './types';
2
+ /** 周期限制只影响当前使用;total_credits 才代表整张卡的次数耗尽。 */
3
+ export declare function getDiscountUsageLimitFailKey(discount: Discount): DiscountFilterRejectKey | null;
4
+ export declare function hasAvailableDiscountBalance(discount: Discount): boolean;
5
+ /** 按卡本身当前生命周期判断;预约时间或一次日程不匹配不代表已失效。 */
6
+ export declare function getDiscountLifecycleReason(discount: Discount): 'disabled' | 'exhausted' | 'expired' | 'not_shared_at_store' | undefined;
7
+ export declare function getDiscountUsageBlockReason(discount: Discount): string | undefined;
@@ -0,0 +1,52 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import dayjs from 'dayjs';
8
+ import Decimal from 'decimal.js';
9
+ import { hasAvailableEntitlementUses, isEntitlementPass } from "./entitlementPass";
10
+
11
+ /** 周期限制只影响当前使用;total_credits 才代表整张卡的次数耗尽。 */
12
+ export function getDiscountUsageLimitFailKey(discount) {
13
+ var _discount$extension_d, _limits$find;
14
+ var value = (_discount$extension_d = discount.extension_data) === null || _discount$extension_d === void 0 || (_discount$extension_d = _discount$extension_d.find(function (field) {
15
+ return field.field_key === 'usage_credits';
16
+ })) === null || _discount$extension_d === void 0 ? void 0 : _discount$extension_d.value;
17
+ if (!value) return null;
18
+ var limits = [['total_credits', discount.total_order_behavior_count], ['per_user_limit', discount.customer_order_behavior_count], ['max_per_day', discount.today_order_behavior_count], ['max_per_week', discount.week_order_behavior_count], ['max_per_month', discount.month_order_behavior_count]];
19
+ return ((_limits$find = limits.find(function (_ref) {
20
+ var _ref2 = _slicedToArray(_ref, 2),
21
+ key = _ref2[0],
22
+ count = _ref2[1];
23
+ return Number(value[key]) > 0 && Number(count || 0) >= Number(value[key]);
24
+ })) === null || _limits$find === void 0 ? void 0 : _limits$find[0]) || null;
25
+ }
26
+ export function hasAvailableDiscountBalance(discount) {
27
+ if (isEntitlementPass(discount)) return hasAvailableEntitlementUses(discount);
28
+ return new Decimal(discount.par_value || 0).minus(discount.used_par_value || 0).greaterThan(0);
29
+ }
30
+
31
+ /** 按卡本身当前生命周期判断;预约时间或一次日程不匹配不代表已失效。 */
32
+ export function getDiscountLifecycleReason(discount) {
33
+ var _discount$franchisee_, _discount$metadata;
34
+ if (discount.is_franchisor_pass === 1 && ((_discount$franchisee_ = discount.franchisee_wallet_pass) === null || _discount$franchisee_ === void 0 ? void 0 : _discount$franchisee_.use) !== 'enabled') {
35
+ return 'not_shared_at_store';
36
+ }
37
+ if (discount.limit_status && discount.limit_status !== 'enable') {
38
+ return 'disabled';
39
+ }
40
+ if ((isEntitlementPass(discount) || discount.par_value != null) && !hasAvailableDiscountBalance(discount) || getDiscountUsageLimitFailKey(discount) === 'total_credits') {
41
+ return 'exhausted';
42
+ }
43
+ // 自定义日程沿用快照语义,不使用遗留固定有效期字段推断过期。
44
+ if (((_discount$metadata = discount.metadata) === null || _discount$metadata === void 0 ? void 0 : _discount$metadata.validity_type) !== 'custom_schedule_validity' && discount.expire_time) {
45
+ var expiry = dayjs(discount.expire_time);
46
+ if (expiry.isValid() && !dayjs().isBefore(expiry)) return 'expired';
47
+ }
48
+ return undefined;
49
+ }
50
+ export function getDiscountUsageBlockReason(discount) {
51
+ return getDiscountLifecycleReason(discount) || getDiscountUsageLimitFailKey(discount) || (discount.unified_available_status != null && String(discount.unified_available_status) !== '' && Number(discount.unified_available_status) === 0 ? 'server_unavailable' : undefined);
52
+ }
@@ -0,0 +1,34 @@
1
+ export declare const ENTITLEMENT_PASS_TYPE = "entitlement_pass";
2
+ export declare const GOOD_PASS_TYPE = "good_pass";
3
+ type DiscountLike = {
4
+ id?: number | string | null;
5
+ tag?: unknown;
6
+ type?: unknown;
7
+ discount?: object | null;
8
+ metadata?: object | null;
9
+ extension_data?: unknown;
10
+ balance?: unknown;
11
+ expire_time?: unknown;
12
+ };
13
+ export type EntitlementQuota = {
14
+ type: 'limited';
15
+ value: number;
16
+ balance: number;
17
+ } | {
18
+ type: 'unlimited';
19
+ value: null;
20
+ balance: null;
21
+ };
22
+ export declare function isEntitlementPass(discount: DiscountLike | null | undefined): boolean;
23
+ export declare function isFullCoveragePass(discount: DiscountLike | null | undefined): boolean;
24
+ /**
25
+ * Resolve the authoritative total-use contract for an Entitlement Pass.
26
+ * Invalid or missing configuration fails closed. Legacy mode/total_uses fields
27
+ * are intentionally unsupported.
28
+ */
29
+ export declare function resolveEntitlementQuota(discount: DiscountLike | null | undefined): EntitlementQuota | null;
30
+ export declare function getRemainingEntitlementUses(discount: DiscountLike | null | undefined, usedCount: number, requestedCount: number): number;
31
+ export declare function hasAvailableEntitlementUses(discount: DiscountLike | null | undefined): boolean;
32
+ /** Sort Entitlement Passes by expiry, finite balance, then card instance id. */
33
+ export declare function compareEntitlementPassPriority(left: DiscountLike, right: DiscountLike): number;
34
+ export {};
@@ -0,0 +1,147 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ import dayjs from 'dayjs';
9
+ export var ENTITLEMENT_PASS_TYPE = 'entitlement_pass';
10
+ export var GOOD_PASS_TYPE = 'good_pass';
11
+ function getDiscountType(discount) {
12
+ var nestedDiscount = discount === null || discount === void 0 ? void 0 : discount.discount;
13
+ return String((discount === null || discount === void 0 ? void 0 : discount.tag) || (discount === null || discount === void 0 ? void 0 : discount.type) || (nestedDiscount === null || nestedDiscount === void 0 ? void 0 : nestedDiscount.tag) || (nestedDiscount === null || nestedDiscount === void 0 ? void 0 : nestedDiscount.type) || '');
14
+ }
15
+ export function isEntitlementPass(discount) {
16
+ return getDiscountType(discount) === ENTITLEMENT_PASS_TYPE;
17
+ }
18
+ export function isFullCoveragePass(discount) {
19
+ var type = getDiscountType(discount);
20
+ return type === GOOD_PASS_TYPE || type === ENTITLEMENT_PASS_TYPE;
21
+ }
22
+ function resolveIncludedUses(discount) {
23
+ var _discount$extension_d;
24
+ var metadata = discount.metadata;
25
+ var hasMetadataIncludedUses = !!metadata && _typeof(metadata) === 'object' && Object.prototype.hasOwnProperty.call(metadata, 'included_uses');
26
+ var rawValue = hasMetadataIncludedUses ? metadata === null || metadata === void 0 ? void 0 : metadata.included_uses : Array.isArray(discount.extension_data) ? (_discount$extension_d = discount.extension_data.find(function (item) {
27
+ return (item === null || item === void 0 ? void 0 : item.field_key) === 'included_uses';
28
+ })) === null || _discount$extension_d === void 0 ? void 0 : _discount$extension_d.value : undefined;
29
+ if (!rawValue || _typeof(rawValue) !== 'object' || Array.isArray(rawValue)) {
30
+ return null;
31
+ }
32
+ var includedUses = rawValue;
33
+ if (includedUses.type === 'unlimited' && includedUses.value === null) {
34
+ return {
35
+ type: 'unlimited',
36
+ value: null
37
+ };
38
+ }
39
+ if (includedUses.type === 'limited' && typeof includedUses.value === 'number' && Number.isInteger(includedUses.value) && includedUses.value >= 1 && includedUses.value <= 9999) {
40
+ return {
41
+ type: 'limited',
42
+ value: includedUses.value
43
+ };
44
+ }
45
+ return null;
46
+ }
47
+ function resolveNonNegativeInteger(value) {
48
+ if (typeof value !== 'number' && typeof value !== 'string' || typeof value === 'string' && value.trim() === '') {
49
+ return null;
50
+ }
51
+ var normalizedValue = Number(value);
52
+ if (!Number.isInteger(normalizedValue) || normalizedValue < 0) return null;
53
+ return normalizedValue;
54
+ }
55
+
56
+ /**
57
+ * Resolve the authoritative total-use contract for an Entitlement Pass.
58
+ * Invalid or missing configuration fails closed. Legacy mode/total_uses fields
59
+ * are intentionally unsupported.
60
+ */
61
+ export function resolveEntitlementQuota(discount) {
62
+ if (!isEntitlementPass(discount)) return null;
63
+ var includedUses = resolveIncludedUses(discount);
64
+ if (!includedUses) return null;
65
+ if (includedUses.type === 'unlimited') {
66
+ return {
67
+ type: 'unlimited',
68
+ value: null,
69
+ balance: null
70
+ };
71
+ }
72
+ var balance = resolveNonNegativeInteger(discount === null || discount === void 0 ? void 0 : discount.balance);
73
+ if (balance === null) return null;
74
+ return {
75
+ type: 'limited',
76
+ value: includedUses.value,
77
+ balance: balance
78
+ };
79
+ }
80
+ export function getRemainingEntitlementUses(discount, usedCount, requestedCount) {
81
+ var quota = resolveEntitlementQuota(discount);
82
+ var normalizedRequestedCount = Math.max(Math.floor(Number(requestedCount) || 0), 0);
83
+ if (!quota || normalizedRequestedCount <= 0) return 0;
84
+ if (quota.type === 'unlimited') return normalizedRequestedCount;
85
+ var normalizedUsedCount = Math.max(Math.floor(Number(usedCount) || 0), 0);
86
+ return Math.min(Math.max(quota.balance - normalizedUsedCount, 0), normalizedRequestedCount);
87
+ }
88
+ export function hasAvailableEntitlementUses(discount) {
89
+ var quota = resolveEntitlementQuota(discount);
90
+ return !!quota && (quota.type === 'unlimited' || quota.balance > 0);
91
+ }
92
+ function resolveExpireTimestamp(value) {
93
+ if (typeof value !== 'string' || !value.trim()) return Number.POSITIVE_INFINITY;
94
+ var normalizedValue = value.trim();
95
+ var calendarParts = normalizedValue.match(/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?/);
96
+ if (calendarParts) {
97
+ var _calendarParts = _slicedToArray(calendarParts, 7),
98
+ year = _calendarParts[1],
99
+ month = _calendarParts[2],
100
+ day = _calendarParts[3],
101
+ _calendarParts$ = _calendarParts[4],
102
+ hour = _calendarParts$ === void 0 ? '0' : _calendarParts$,
103
+ _calendarParts$2 = _calendarParts[5],
104
+ minute = _calendarParts$2 === void 0 ? '0' : _calendarParts$2,
105
+ _calendarParts$3 = _calendarParts[6],
106
+ second = _calendarParts$3 === void 0 ? '0' : _calendarParts$3;
107
+ var yearNumber = Number(year);
108
+ var monthNumber = Number(month);
109
+ var dayNumber = Number(day);
110
+ var hourNumber = Number(hour);
111
+ var minuteNumber = Number(minute);
112
+ var secondNumber = Number(second);
113
+ var daysInMonth = new Date(Date.UTC(yearNumber, monthNumber, 0)).getUTCDate();
114
+ if (yearNumber <= 0 || monthNumber < 1 || monthNumber > 12 || dayNumber < 1 || dayNumber > daysInMonth || hourNumber < 0 || hourNumber > 23 || minuteNumber < 0 || minuteNumber > 59 || secondNumber < 0 || secondNumber > 59) {
115
+ return Number.POSITIVE_INFINITY;
116
+ }
117
+ }
118
+ var date = dayjs(normalizedValue);
119
+ return date.isValid() ? date.valueOf() : Number.POSITIVE_INFINITY;
120
+ }
121
+ function compareIds(left, right) {
122
+ var leftNumber = Number(left);
123
+ var rightNumber = Number(right);
124
+ if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {
125
+ return leftNumber - rightNumber;
126
+ }
127
+ return String(left !== null && left !== void 0 ? left : '').localeCompare(String(right !== null && right !== void 0 ? right : ''), undefined, {
128
+ numeric: true
129
+ });
130
+ }
131
+
132
+ /** Sort Entitlement Passes by expiry, finite balance, then card instance id. */
133
+ export function compareEntitlementPassPriority(left, right) {
134
+ var expireDifference = resolveExpireTimestamp(left.expire_time) - resolveExpireTimestamp(right.expire_time);
135
+ if (!Number.isNaN(expireDifference) && expireDifference !== 0) {
136
+ return expireDifference;
137
+ }
138
+ var leftQuota = resolveEntitlementQuota(left);
139
+ var rightQuota = resolveEntitlementQuota(right);
140
+ var leftBalance = (leftQuota === null || leftQuota === void 0 ? void 0 : leftQuota.type) === 'limited' ? leftQuota.balance : Number.POSITIVE_INFINITY;
141
+ var rightBalance = (rightQuota === null || rightQuota === void 0 ? void 0 : rightQuota.type) === 'limited' ? rightQuota.balance : Number.POSITIVE_INFINITY;
142
+ var balanceDifference = leftBalance - rightBalance;
143
+ if (!Number.isNaN(balanceDifference) && balanceDifference !== 0) {
144
+ return balanceDifference;
145
+ }
146
+ return compareIds(left.id, right.id);
147
+ }
@@ -0,0 +1,8 @@
1
+ import type { Discount } from './types';
2
+ export declare function hasEntitlementDiscount(product: any): boolean;
3
+ export declare function isPersistedEntitlementLine(product: any, mappedProduct?: any): boolean;
4
+ /** Refresh authoritative balances while retaining the user's scan/selection state. */
5
+ export declare function mergeEntitlementDiscountLists(current: Discount[], incoming: Discount[], observed?: Discount[]): Discount[];
6
+ export declare function retainScannedEntitlements(current: Discount[], scanned: Discount[]): Discount[];
7
+ /** Historical uses are display records; backend balance already excludes them. */
8
+ export declare function withCommittedEntitlementDetails(discounts: Discount[], products: any[], getProduct: (item: any) => any): Discount[];