@pisell/pisellos 0.10.40 → 0.10.42

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 (73) hide show
  1. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +58 -19
  2. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +24 -12
  3. package/dist/modules/Customer/index.js +4 -2
  4. package/dist/modules/Customer/types.d.ts +2 -0
  5. package/dist/modules/Discount/entitlementPass.d.ts +34 -0
  6. package/dist/modules/Discount/entitlementPass.js +147 -0
  7. package/dist/modules/Discount/index.d.ts +2 -0
  8. package/dist/modules/Discount/index.js +39 -13
  9. package/dist/modules/Discount/types.d.ts +26 -5
  10. package/dist/modules/Order/index.d.ts +6 -1
  11. package/dist/modules/Order/index.js +283 -118
  12. package/dist/modules/Order/utils/orderCollectionIdentity.js +16 -12
  13. package/dist/modules/Order/utils.js +17 -1
  14. package/dist/modules/Payment/types.d.ts +21 -1
  15. package/dist/modules/Payment/types.js +2 -0
  16. package/dist/modules/Payment/walletpass.d.ts +1 -1
  17. package/dist/modules/Payment/walletpass.js +80 -47
  18. package/dist/modules/ResourcePlanner/planner.d.ts +2 -2
  19. package/dist/modules/ResourcePlanner/planner.js +163 -46
  20. package/dist/modules/ResourcePlanner/types.d.ts +17 -0
  21. package/dist/modules/Rules/index.js +310 -134
  22. package/dist/solution/BaseSales/index.d.ts +3 -0
  23. package/dist/solution/BaseSales/index.js +11 -2
  24. package/dist/solution/BaseSales/utils/cartPromotion.js +141 -126
  25. package/dist/solution/BookingByStep/index.d.ts +2 -2
  26. package/dist/solution/BookingTicket/index.d.ts +1 -2
  27. package/dist/solution/BookingTicket/index.js +60 -63
  28. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
  29. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +266 -150
  30. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +7 -3
  31. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +4 -0
  32. package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +8 -4
  33. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  34. package/dist/solution/ShopDiscount/index.js +41 -21
  35. package/dist/solution/ShopDiscount/utils.js +3 -2
  36. package/dist/solution/UnifiedBookingSales/index.js +94 -21
  37. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +35 -6
  38. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +13 -6
  39. package/lib/modules/Customer/index.js +4 -1
  40. package/lib/modules/Customer/types.d.ts +2 -0
  41. package/lib/modules/Discount/entitlementPass.d.ts +34 -0
  42. package/lib/modules/Discount/entitlementPass.js +141 -0
  43. package/lib/modules/Discount/index.d.ts +2 -0
  44. package/lib/modules/Discount/index.js +25 -9
  45. package/lib/modules/Discount/types.d.ts +26 -5
  46. package/lib/modules/Order/index.d.ts +6 -1
  47. package/lib/modules/Order/index.js +172 -28
  48. package/lib/modules/Order/utils/orderCollectionIdentity.js +14 -11
  49. package/lib/modules/Order/utils.js +19 -1
  50. package/lib/modules/Payment/types.d.ts +21 -1
  51. package/lib/modules/Payment/types.js +1 -0
  52. package/lib/modules/Payment/walletpass.d.ts +1 -1
  53. package/lib/modules/Payment/walletpass.js +29 -9
  54. package/lib/modules/ResourcePlanner/planner.d.ts +2 -2
  55. package/lib/modules/ResourcePlanner/planner.js +137 -35
  56. package/lib/modules/ResourcePlanner/types.d.ts +17 -0
  57. package/lib/modules/Rules/index.js +230 -96
  58. package/lib/solution/BaseSales/index.d.ts +3 -0
  59. package/lib/solution/BaseSales/index.js +9 -2
  60. package/lib/solution/BaseSales/utils/cartPromotion.js +12 -4
  61. package/lib/solution/BookingByStep/index.d.ts +2 -2
  62. package/lib/solution/BookingTicket/index.d.ts +1 -2
  63. package/lib/solution/BookingTicket/index.js +36 -33
  64. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
  65. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +127 -42
  66. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +7 -3
  67. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +4 -0
  68. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +7 -3
  69. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  70. package/lib/solution/ShopDiscount/index.js +26 -6
  71. package/lib/solution/ShopDiscount/utils.js +3 -2
  72. package/lib/solution/UnifiedBookingSales/index.js +86 -22
  73. package/package.json +1 -1
@@ -142,7 +142,7 @@ function buildPlannerDiscountResult(params) {
142
142
  const productDiscounts = [...(Array.isArray(product.discount_list) ? product.discount_list : []), ...(Array.isArray(product.product_bundle) ? product.product_bundle.flatMap(bundle => bundle?.discount_list || []) : [])];
143
143
  productDiscounts.forEach(discount => {
144
144
  const type = discount.tag || discount.type;
145
- if (!['good_pass', 'discount_card', 'product_discount_card'].includes(type)) return;
145
+ if (!['entitlement_pass', 'good_pass', 'discount_card', 'product_discount_card'].includes(type)) return;
146
146
  const discountId = resolvePlannerDiscountId(discount);
147
147
  applications.push({
148
148
  discountId,
@@ -184,7 +184,7 @@ function isLocalOrderId(orderId) {
184
184
  }
185
185
  function isCustomerBoundDiscount(discount) {
186
186
  const type = discount?.type ?? discount?.tag;
187
- return type === 'good_pass' || type === 'discount_card' || type === 'product_discount_card';
187
+ return type === 'entitlement_pass' || type === 'good_pass' || type === 'discount_card' || type === 'product_discount_card';
188
188
  }
189
189
  function filterCustomerBoundDiscounts(discountList) {
190
190
  if (!Array.isArray(discountList)) return [];
@@ -639,6 +639,22 @@ function normalizeResource(raw, fixedOffsetMinutes = (0, _localClock.captureRunt
639
639
  const id = raw.resourceId ?? raw.resource_id ?? raw.id;
640
640
  if (id === undefined || id === null || id === '') return null;
641
641
  const rawWindows = raw.windows || raw.times || [];
642
+ const rawExcludedWindows = raw.excludedWindows || raw.excluded_windows || [];
643
+ const normalizeWindows = windows => (Array.isArray(windows) ? windows : []).flatMap(window => {
644
+ const range = normalizeAvailabilityLocalDateTimeRange({
645
+ startAt: window.startAt || window.start_at || window.start,
646
+ endAt: window.endAt || window.end_at || window.end,
647
+ fixedOffsetMinutes,
648
+ rollOverEnd: true
649
+ });
650
+ if (!range) return [];
651
+ return [{
652
+ startAt: range.startAt,
653
+ endAt: range.endAt,
654
+ source: window.source,
655
+ raw: window
656
+ }];
657
+ });
642
658
  return {
643
659
  id,
644
660
  formId: raw.formId ?? raw.form_id ?? raw.resource_form_id,
@@ -646,21 +662,8 @@ function normalizeResource(raw, fixedOffsetMinutes = (0, _localClock.captureRunt
646
662
  code: raw.code,
647
663
  resourceType: normalizeResourceType(raw.type || raw.resourceType),
648
664
  capacity: Math.max(1, Number(raw.capacity || raw.max_capacity || 1) || 1),
649
- windows: (Array.isArray(rawWindows) ? rawWindows : []).flatMap(window => {
650
- const range = normalizeAvailabilityLocalDateTimeRange({
651
- startAt: window.startAt || window.start_at || window.start,
652
- endAt: window.endAt || window.end_at || window.end,
653
- fixedOffsetMinutes,
654
- rollOverEnd: true
655
- });
656
- if (!range) return [];
657
- return [{
658
- startAt: range.startAt,
659
- endAt: range.endAt,
660
- source: window.source,
661
- raw: window
662
- }];
663
- }),
665
+ windows: normalizeWindows(rawWindows),
666
+ excludedWindows: normalizeWindows(rawExcludedWindows),
664
667
  raw
665
668
  };
666
669
  }
@@ -679,6 +682,17 @@ function dateRangeDays(dateRange) {
679
682
  }
680
683
  return dates;
681
684
  }
685
+ function getExcludedScheduleDateOverrideTimePoints(date, schedule) {
686
+ if (!schedule.repeat_rule?.excluded_date?.length) return [];
687
+ if ((0, _getDateIsInSchedule.getScheduleStartEndTimePoints)(date, [schedule]).length > 0) return [];
688
+ return (0, _getDateIsInSchedule.getScheduleStartEndTimePoints)(date, [{
689
+ ...schedule,
690
+ repeat_rule: {
691
+ ...schedule.repeat_rule,
692
+ excluded_date: []
693
+ }
694
+ }]);
695
+ }
682
696
  function normalizeResourceOccupancy(rawEvent, resourceId, source = 'remote', fixedOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)()) {
683
697
  const range = normalizeAvailabilityLocalDateTimeRange({
684
698
  startAt: rawEvent.start_at ?? rawEvent.startAt ?? rawEvent.start_time ?? rawEvent.startTime,
@@ -771,7 +785,26 @@ function buildAvailabilityResourcesFromV2(params) {
771
785
  }
772
786
  }];
773
787
  })));
788
+ const excludedWindows = dates.flatMap(date => schedules.flatMap(schedule => getExcludedScheduleDateOverrideTimePoints(date, schedule).flatMap(slot => {
789
+ const range = normalizeAvailabilityLocalDateTimeRange({
790
+ startAt: slot.start_at,
791
+ endAt: slot.end_at,
792
+ fixedOffsetMinutes,
793
+ rollOverEnd: true
794
+ });
795
+ if (!range) return [];
796
+ return [{
797
+ startAt: range.startAt,
798
+ endAt: range.endAt,
799
+ source: `resource_schedule_excluded:${schedule.id}`,
800
+ raw: {
801
+ scheduleId: schedule.id,
802
+ excludedDate: date
803
+ }
804
+ }];
805
+ })));
774
806
  resource.windows = materializedWindows.length > 0 ? materializedWindows : explicitWindows;
807
+ resource.excludedWindows = [...(resource.excludedWindows || []), ...excludedWindows];
775
808
  if (resource.windows.length === 0 && missingScheduleIds.length > 0) {
776
809
  resource.windows = buildResourceWindowFallbackTimes({
777
810
  raw,
@@ -1012,7 +1045,7 @@ function buildBookingFromAvailabilitySelection(params) {
1012
1045
  }
1013
1046
  };
1014
1047
  }
1015
- const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
1048
+ const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'schedule_excluded_date', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
1016
1049
  // A required group whose selected resource is outside its window is surfaced
1017
1050
  // as missing_resource at group level. Structural validation below still
1018
1051
  // rejects a genuinely missing selection.
@@ -2147,11 +2180,31 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2147
2180
  source: `operating_schedule:${descriptor.scheduleIds.map(String).join(',')}`
2148
2181
  }] : [];
2149
2182
  }));
2183
+ const excludedWindows = dateRangeDays(params.dateRange).flatMap(date => schedules.flatMap(schedule => getExcludedScheduleDateOverrideTimePoints(date, schedule).flatMap(slot => {
2184
+ const range = normalizeAvailabilityLocalDateTimeRange({
2185
+ startAt: slot.start_at,
2186
+ endAt: slot.end_at,
2187
+ fixedOffsetMinutes: this.getAvailabilityRuntimeOffsetMinutes(),
2188
+ rollOverEnd: true
2189
+ });
2190
+ return range ? [{
2191
+ startAt: range.startAt,
2192
+ endAt: range.endAt,
2193
+ source: `operating_schedule_excluded:${schedule.id}`,
2194
+ raw: {
2195
+ scheduleId: schedule.id,
2196
+ excludedDate: date
2197
+ }
2198
+ }] : [];
2199
+ })));
2150
2200
  return {
2151
2201
  source: descriptor.source,
2152
2202
  scheduleIds: [...descriptor.scheduleIds],
2153
2203
  missingScheduleIds,
2154
- windows
2204
+ windows,
2205
+ ...(excludedWindows.length > 0 ? {
2206
+ excludedWindows
2207
+ } : {})
2155
2208
  };
2156
2209
  }
2157
2210
  async loadAvailabilityProducts(params) {
@@ -2849,7 +2902,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2849
2902
  } : {})
2850
2903
  }, {
2851
2904
  evaluatedAt: this.getAvailabilityRuntimeDateTime(),
2852
- allowSessionCustomRanges: isPosAvailabilityRequest
2905
+ useExactDurationCandidateMinute: isPosAvailabilityRequest,
2906
+ allowSessionCustomRanges: isPosAvailabilityRequest,
2907
+ allowExcludedScheduleDateOverride: isPosAvailabilityRequest
2853
2908
  }).map(group => ({
2854
2909
  ...group,
2855
2910
  ranges: group.ranges.map(candidate => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
@@ -2864,7 +2919,11 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2864
2919
  refreshed
2865
2920
  } = await this.ensureAvailabilityContextProjection(contextId, 'query_booking_availability');
2866
2921
  this.assertContextualQueryFreshness(context, request);
2867
- const result = (0, _ResourcePlanner.queryAvailabilityProjection)(projectionEntry.projection, request);
2922
+ const isPosAvailabilityRequest = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos';
2923
+ const result = (0, _ResourcePlanner.queryAvailabilityProjection)(projectionEntry.projection, request, {
2924
+ useExactDurationCandidateMinute: isPosAvailabilityRequest,
2925
+ allowExcludedScheduleDateOverride: isPosAvailabilityRequest
2926
+ });
2868
2927
  const contextVersion = context.activeVersion;
2869
2928
  const contextualResult = result.target === 'time' ? {
2870
2929
  ...result,
@@ -3121,7 +3180,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3121
3180
  } : {})
3122
3181
  } : {})
3123
3182
  }, {
3124
- allowSessionCustomRanges: allowPosAvailabilityOverride
3183
+ useExactDurationCandidateMinute: allowPosAvailabilityOverride,
3184
+ allowSessionCustomRanges: allowPosAvailabilityOverride,
3185
+ allowExcludedScheduleDateOverride: allowPosAvailabilityOverride
3125
3186
  }).flatMap(group => group.ranges);
3126
3187
  const refreshedCandidateBase = refreshedRanges.find(candidate => candidate.startAt === params.candidate.startAt && candidate.endAt === params.candidate.endAt && candidate.bookingStartAt === params.candidate.bookingStartAt && candidate.bookingEndAt === params.candidate.bookingEndAt);
3127
3188
  if (!refreshedCandidateBase) {
@@ -3142,6 +3203,9 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3142
3203
  requirementSelections: params.requirementSelections,
3143
3204
  partySize,
3144
3205
  bookingCount
3206
+ }, {
3207
+ useExactDurationCandidateMinute: allowPosAvailabilityOverride,
3208
+ allowExcludedScheduleDateOverride: allowPosAvailabilityOverride
3145
3209
  });
3146
3210
  if (allowPosAvailabilityOverride && !validation.ok && validation.conflicts.every(conflict => POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES.has(conflict.code))) {
3147
3211
  const forced = buildPosForcedAvailabilityAssignments({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.10.40",
4
+ "version": "0.10.42",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",