@pisell/pisellos 0.10.44 → 0.10.46

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 (43) hide show
  1. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  2. package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
  3. package/dist/modules/Customer/index.js +2 -1
  4. package/dist/modules/Discount/availability.d.ts +7 -0
  5. package/dist/modules/Discount/availability.js +49 -0
  6. package/dist/modules/Discount/index.d.ts +1 -3
  7. package/dist/modules/Discount/index.js +12 -151
  8. package/dist/modules/Discount/types.d.ts +6 -0
  9. package/dist/modules/Order/index.d.ts +1 -1
  10. package/dist/modules/Order/index.js +155 -130
  11. package/dist/modules/Order/utils.d.ts +1 -1
  12. package/dist/modules/Order/utils.js +84 -59
  13. package/dist/modules/ResourcePlanner/planner.js +9 -5
  14. package/dist/modules/ResourcePlanner/types.d.ts +2 -1
  15. package/dist/modules/Rules/index.js +50 -16
  16. package/dist/solution/BaseSales/types.d.ts +2 -2
  17. package/dist/solution/BookingByStep/index.d.ts +1 -1
  18. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  19. package/dist/solution/ShopDiscount/index.js +59 -22
  20. package/dist/solution/ShopDiscount/utils.d.ts +4 -2
  21. package/dist/solution/ShopDiscount/utils.js +40 -21
  22. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  23. package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
  24. package/lib/modules/Customer/index.js +1 -0
  25. package/lib/modules/Discount/availability.d.ts +7 -0
  26. package/lib/modules/Discount/availability.js +43 -0
  27. package/lib/modules/Discount/index.d.ts +1 -3
  28. package/lib/modules/Discount/index.js +10 -131
  29. package/lib/modules/Discount/types.d.ts +6 -0
  30. package/lib/modules/Order/index.d.ts +1 -1
  31. package/lib/modules/Order/index.js +22 -8
  32. package/lib/modules/Order/utils.d.ts +1 -1
  33. package/lib/modules/Order/utils.js +20 -2
  34. package/lib/modules/ResourcePlanner/planner.js +9 -5
  35. package/lib/modules/ResourcePlanner/types.d.ts +2 -1
  36. package/lib/modules/Rules/index.js +42 -5
  37. package/lib/solution/BaseSales/types.d.ts +2 -2
  38. package/lib/solution/BookingByStep/index.d.ts +1 -1
  39. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  40. package/lib/solution/ShopDiscount/index.js +29 -3
  41. package/lib/solution/ShopDiscount/utils.d.ts +4 -2
  42. package/lib/solution/ShopDiscount/utils.js +39 -23
  43. package/package.json +1 -1
@@ -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
 
@@ -203,7 +203,8 @@ export var CustomerModule = /*#__PURE__*/function (_BaseModule) {
203
203
  sort_by: SORT_BY,
204
204
  with: ['latestWalletDetail.wallet', 'contactsInfo', 'formRecord'],
205
205
  search_wallet_flag: 1,
206
- search_wallet_pass_flag: 1
206
+ search_wallet_pass_flag: 1,
207
+ filter_franchisor_permissions: ['use']
207
208
  }, search && {
208
209
  search: search
209
210
  }), _otherParams), url === '/customer/select-list' ? {
@@ -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' | undefined;
7
+ export declare function getDiscountUsageBlockReason(discount: Discount): string | undefined;
@@ -0,0 +1,49 @@
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$metadata;
34
+ if (discount.limit_status && discount.limit_status !== 'enable') {
35
+ return 'disabled';
36
+ }
37
+ if ((isEntitlementPass(discount) || discount.par_value != null) && !hasAvailableDiscountBalance(discount) || getDiscountUsageLimitFailKey(discount) === 'total_credits') {
38
+ return 'exhausted';
39
+ }
40
+ // 自定义日程沿用快照语义,不使用遗留固定有效期字段推断过期。
41
+ if (((_discount$metadata = discount.metadata) === null || _discount$metadata === void 0 ? void 0 : _discount$metadata.validity_type) !== 'custom_schedule_validity' && discount.expire_time) {
42
+ var expiry = dayjs(discount.expire_time);
43
+ if (expiry.isValid() && !dayjs().isBefore(expiry)) return 'expired';
44
+ }
45
+ return undefined;
46
+ }
47
+ export function getDiscountUsageBlockReason(discount) {
48
+ return getDiscountLifecycleReason(discount) || getDiscountUsageLimitFailKey(discount) || (discount.unified_available_status != null && String(discount.unified_available_status) !== '' && Number(discount.unified_available_status) === 0 ? 'server_unavailable' : undefined);
49
+ }
@@ -27,6 +27,7 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
27
27
  with_available_wallet_pass_flag?: 0 | 1;
28
28
  with_virtual_currency?: 0 | 1;
29
29
  with_entitlement_pass?: 0 | 1;
30
+ filter_order_wallet_pass_usage?: 0 | 1;
30
31
  request_timezone: string;
31
32
  order_id?: number | string;
32
33
  }): Promise<DiscountPrepareConfigResult>;
@@ -37,10 +38,7 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
37
38
  }): Promise<DiscountWithReason>;
38
39
  batchSearchByProductIds(productIds: number[]): Promise<any>;
39
40
  filterEnabledDiscountList(discountList: Discount[]): Discount[];
40
- private hasAvailableBalance;
41
- private checkUsageCreditsLimit;
42
41
  filterEnabledDiscountListWithReason(discountList: Discount[]): DiscountWithReason;
43
- private checkUsageCreditsLimitWithFailKey;
44
42
  uniqueByProductId(discountList: Discount[]): Discount[];
45
43
  filterDiscountListByProductIds(discountList: Discount[], productIds: number[]): Discount[];
46
44
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
@@ -29,7 +29,7 @@ import { uniqueById } from "../../solution/ShopDiscount/utils";
29
29
  import { BaseModule } from "../BaseModule";
30
30
  import { DiscountHooks } from "./types";
31
31
  import Decimal from 'decimal.js';
32
- import { hasAvailableEntitlementUses, isEntitlementPass } from "./entitlementPass";
32
+ import { getDiscountLifecycleReason, getDiscountUsageBlockReason, getDiscountUsageLimitFailKey, hasAvailableDiscountBalance } from "./availability";
33
33
  export var DiscountModule = /*#__PURE__*/function (_BaseModule) {
34
34
  _inherits(DiscountModule, _BaseModule);
35
35
  var _super = _createSuper(DiscountModule);
@@ -325,169 +325,30 @@ export var DiscountModule = /*#__PURE__*/function (_BaseModule) {
325
325
  return _batchSearchByProductIds.apply(this, arguments);
326
326
  }
327
327
  return batchSearchByProductIds;
328
- }()
328
+ }() // 展示列表只剔除已失效项,当前不可用项保留并携带原因。
329
329
  }, {
330
330
  key: "filterEnabledDiscountList",
331
331
  value: function filterEnabledDiscountList(discountList) {
332
- var _this2 = this;
333
332
  return discountList.filter(function (discount) {
334
- return discount.limit_status === 'enable' && _this2.hasAvailableBalance(discount) && _this2.checkUsageCreditsLimit(discount);
335
- });
336
- }
337
- }, {
338
- key: "hasAvailableBalance",
339
- value: function hasAvailableBalance(discount) {
340
- if (isEntitlementPass(discount)) {
341
- return hasAvailableEntitlementUses(discount);
342
- }
343
-
344
- // good_pass 与折扣卡继续沿用原有金额余额判断。
345
- return new Decimal((discount === null || discount === void 0 ? void 0 : discount.par_value) || 0).minus(new Decimal((discount === null || discount === void 0 ? void 0 : discount.used_par_value) || 0)).greaterThan(0);
346
- }
347
-
348
- // 检查使用次数限制
349
- }, {
350
- key: "checkUsageCreditsLimit",
351
- value: function checkUsageCreditsLimit(discount) {
352
- // 如果没有 extension_data,则不需要限制
353
- if (!discount.extension_data || discount.extension_data.length === 0) {
354
- return true;
355
- }
356
-
357
- // 查找 field_key 为 usage_credits 的数据
358
- var usageCreditsData = discount.extension_data.find(function (data) {
359
- return data.field_key === 'usage_credits';
333
+ return discount.limit_status === 'enable' && hasAvailableDiscountBalance(discount) && !getDiscountLifecycleReason(discount);
334
+ }).map(function (discount) {
335
+ return _objectSpread(_objectSpread({}, discount), {}, {
336
+ usageLimitFailKey: getDiscountUsageLimitFailKey(discount),
337
+ reasonCode: getDiscountUsageBlockReason(discount)
338
+ });
360
339
  });
361
-
362
- // 如果没有找到 usage_credits 数据,则不需要限制
363
- if (!usageCreditsData) {
364
- return true;
365
- }
366
- var value = usageCreditsData.value;
367
-
368
- // 检查总次数限制
369
- if (value.total_credits && value.total_credits > 0) {
370
- if ((discount.total_order_behavior_count || 0) >= value.total_credits) {
371
- return false;
372
- }
373
- }
374
-
375
- // 检查单用户限制
376
- if (value.per_user_limit && value.per_user_limit > 0) {
377
- if ((discount.customer_order_behavior_count || 0) >= value.per_user_limit) {
378
- return false;
379
- }
380
- }
381
-
382
- // 检查单日限制
383
- if (value.max_per_day && value.max_per_day > 0) {
384
- if ((discount.today_order_behavior_count || 0) >= value.max_per_day) {
385
- return false;
386
- }
387
- }
388
-
389
- // 检查单周限制
390
- if (value.max_per_week && value.max_per_week > 0) {
391
- if ((discount.week_order_behavior_count || 0) >= value.max_per_week) {
392
- return false;
393
- }
394
- }
395
-
396
- // 检查单月限制
397
- if (value.max_per_month && value.max_per_month > 0) {
398
- if ((discount.month_order_behavior_count || 0) >= value.max_per_month) {
399
- return false;
400
- }
401
- }
402
-
403
- // 所有检查都通过
404
- return true;
405
340
  }
406
-
407
- // 过滤启用且可用的优惠券,并返回校验失败原因
408
341
  }, {
409
342
  key: "filterEnabledDiscountListWithReason",
410
343
  value: function filterEnabledDiscountListWithReason(discountList) {
411
- var _this3 = this;
412
- var lists = discountList.filter(function (discount) {
413
- return discount.limit_status === 'enable';
414
- }).filter(function (discount) {
415
- return _this3.hasAvailableBalance(discount);
416
- }).map(function (discount) {
417
- var limitFailKey = _this3.checkUsageCreditsLimitWithFailKey(discount);
418
- return _objectSpread(_objectSpread({}, discount), {}, {
419
- usageLimitFailKey: limitFailKey
420
- });
421
- });
422
-
423
- // 可用的列表
424
- var availableLists = lists.filter(function (item) {
425
- return !item.usageLimitFailKey && item.unified_available_status !== 0;
426
- });
427
- // 不可用数据
428
- var currentFailDiscount = lists.find(function (item) {
429
- return item.usageLimitFailKey;
430
- });
431
344
  return {
432
- discountList: availableLists,
433
- unavailableReasonKey: currentFailDiscount === null || currentFailDiscount === void 0 ? void 0 : currentFailDiscount.usageLimitFailKey
345
+ discountList: this.filterEnabledDiscountList(discountList),
346
+ unavailableReasonKey: discountList.map(getDiscountUsageLimitFailKey).find(function (key) {
347
+ return key !== null;
348
+ }) || null
434
349
  };
435
350
  }
436
351
 
437
- // 检查使用次数限制,并返回校验失败原因
438
- }, {
439
- key: "checkUsageCreditsLimitWithFailKey",
440
- value: function checkUsageCreditsLimitWithFailKey(discount) {
441
- if (!discount.extension_data || discount.extension_data.length === 0) {
442
- return null;
443
- }
444
- var usageCreditsData = discount.extension_data.find(function (data) {
445
- return data.field_key === 'usage_credits';
446
- });
447
- if (!usageCreditsData) {
448
- return null;
449
- }
450
- var value = usageCreditsData.value;
451
-
452
- // 总次数限制
453
- if (value.total_credits && value.total_credits > 0) {
454
- if ((discount.total_order_behavior_count || 0) >= value.total_credits) {
455
- return 'total_credits';
456
- }
457
- }
458
-
459
- // 单用户限制
460
- if (value.per_user_limit && value.per_user_limit > 0) {
461
- if ((discount.customer_order_behavior_count || 0) >= value.per_user_limit) {
462
- return 'per_user_limit';
463
- }
464
- }
465
-
466
- // 单日限制
467
- if (value.max_per_day && value.max_per_day > 0) {
468
- if ((discount.today_order_behavior_count || 0) >= value.max_per_day) {
469
- return 'max_per_day';
470
- }
471
- }
472
-
473
- // 单周限制
474
- if (value.max_per_week && value.max_per_week > 0) {
475
- if ((discount.week_order_behavior_count || 0) >= value.max_per_week) {
476
- return 'max_per_week';
477
- }
478
- }
479
-
480
- // 单月限制
481
- if (value.max_per_month && value.max_per_month > 0) {
482
- if ((discount.month_order_behavior_count || 0) >= value.max_per_month) {
483
- return 'max_per_month';
484
- }
485
- }
486
-
487
- // 全部通过
488
- return null;
489
- }
490
-
491
352
  // 根据productIds去重
492
353
  }, {
493
354
  key: "uniqueByProductId",
@@ -201,6 +201,12 @@ export interface Discount {
201
201
  start_time?: string;
202
202
  discount_rule_uncheck_flag?: boolean;
203
203
  usageLimitFailKey?: string | null;
204
+ /** 本次规则计算的不可用原因;可用性恢复后清除。 */
205
+ reason?: string;
206
+ reasonCode?: string;
207
+ unified_messages?: {
208
+ title?: string | Record<string, string>;
209
+ };
204
210
  unified_available_status?: number | undefined | null;
205
211
  }
206
212
  export interface DiscountState {
@@ -572,7 +572,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
572
572
  generateIdempotencyToken(): string;
573
573
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
574
574
  createOrder(params: CommitOrderParams['query']): {
575
- type: "virtual" | "appointment_booking";
575
+ type: "appointment_booking" | "virtual";
576
576
  platform: string;
577
577
  sales_channel: string;
578
578
  order_sales_channel: string;