@pisell/pisellos 0.10.8 → 0.10.10

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 (129) hide show
  1. package/dist/core/index.js +0 -1
  2. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.js +287 -101
  4. package/dist/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  5. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
  6. package/dist/model/strategy/adapter/walletPass/type.d.ts +5 -0
  7. package/dist/model/strategy/adapter/walletPass/utils.js +57 -26
  8. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  9. package/dist/modules/BookingContext/utils/productExtend.js +5 -9
  10. package/dist/modules/BookingContext/utils/timeSlices.js +24 -3
  11. package/dist/modules/Customer/index.d.ts +4 -0
  12. package/dist/modules/Customer/index.js +91 -59
  13. package/dist/modules/Customer/types.d.ts +2 -0
  14. package/dist/modules/Discount/index.d.ts +2 -0
  15. package/dist/modules/Discount/index.js +38 -5
  16. package/dist/modules/Discount/types.d.ts +11 -0
  17. package/dist/modules/OpenData/types.d.ts +1 -0
  18. package/dist/modules/Order/index.d.ts +20 -1
  19. package/dist/modules/Order/index.js +976 -730
  20. package/dist/modules/Order/types.d.ts +6 -1
  21. package/dist/modules/Order/utils/virtualSettlement.d.ts +56 -0
  22. package/dist/modules/Order/utils/virtualSettlement.js +271 -0
  23. package/dist/modules/Order/utils.js +89 -48
  24. package/dist/modules/Payment/types.d.ts +2 -0
  25. package/dist/modules/Payment/utils.js +4 -1
  26. package/dist/modules/Payment/walletpass.d.ts +11 -0
  27. package/dist/modules/Payment/walletpass.js +235 -60
  28. package/dist/modules/Product/types.d.ts +23 -0
  29. package/dist/modules/ProductList/index.d.ts +15 -2
  30. package/dist/modules/ProductList/index.js +92 -13
  31. package/dist/modules/ResourcePlanner/index.d.ts +0 -22
  32. package/dist/modules/ResourcePlanner/index.js +1 -180
  33. package/dist/modules/ResourcePlanner/localClock.d.ts +33 -0
  34. package/dist/modules/ResourcePlanner/localClock.js +183 -0
  35. package/dist/modules/ResourcePlanner/planner.d.ts +5 -14
  36. package/dist/modules/ResourcePlanner/planner.js +2019 -936
  37. package/dist/modules/ResourcePlanner/types.d.ts +346 -187
  38. package/dist/modules/ResourcePlanner/types.js +33 -1
  39. package/dist/modules/SalesSummary/index.d.ts +1 -0
  40. package/dist/modules/SalesSummary/index.js +4 -3
  41. package/dist/modules/SalesSummary/types.d.ts +1 -0
  42. package/dist/modules/SalesSummary/utils.d.ts +1 -0
  43. package/dist/modules/SalesSummary/utils.js +21 -1
  44. package/dist/server/index.d.ts +9 -0
  45. package/dist/server/index.js +90 -58
  46. package/dist/server/modules/order/index.d.ts +1 -0
  47. package/dist/server/modules/order/index.js +252 -94
  48. package/dist/server/utils/small-ticket.js +2 -1
  49. package/dist/solution/BaseSales/index.d.ts +26 -2
  50. package/dist/solution/BaseSales/index.js +1310 -931
  51. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  52. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +78 -12
  53. package/dist/solution/BookingByStep/index.d.ts +4 -4
  54. package/dist/solution/BookingTicket/index.d.ts +5 -1
  55. package/dist/solution/BookingTicket/index.js +225 -161
  56. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
  57. package/dist/solution/BookingTicket/utils/addProductDecision.js +5 -3
  58. package/dist/solution/ScanOrder/index.js +25 -64
  59. package/dist/solution/UnifiedBookingSales/index.d.ts +110 -73
  60. package/dist/solution/UnifiedBookingSales/index.js +3349 -971
  61. package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
  62. package/dist/solution/UnifiedBookingSales/remoteOccupancyCache.js +430 -0
  63. package/dist/solution/UnifiedBookingSales/types.d.ts +133 -76
  64. package/dist/solution/UnifiedBookingSales/types.js +4 -9
  65. package/lib/core/index.js +0 -1
  66. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +18 -2
  67. package/lib/model/strategy/adapter/dataVariant/evaluator.js +170 -7
  68. package/lib/model/strategy/adapter/dataVariant/type.d.ts +25 -0
  69. package/lib/model/strategy/adapter/walletPass/evaluator.js +0 -2
  70. package/lib/model/strategy/adapter/walletPass/type.d.ts +5 -0
  71. package/lib/model/strategy/adapter/walletPass/utils.js +62 -11
  72. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  73. package/lib/modules/BookingContext/utils/productExtend.js +4 -3
  74. package/lib/modules/BookingContext/utils/timeSlices.js +18 -3
  75. package/lib/modules/Customer/index.d.ts +4 -0
  76. package/lib/modules/Customer/index.js +11 -0
  77. package/lib/modules/Customer/types.d.ts +2 -0
  78. package/lib/modules/Discount/index.d.ts +2 -0
  79. package/lib/modules/Discount/index.js +37 -3
  80. package/lib/modules/Discount/types.d.ts +11 -0
  81. package/lib/modules/OpenData/types.d.ts +1 -0
  82. package/lib/modules/Order/index.d.ts +20 -1
  83. package/lib/modules/Order/index.js +393 -128
  84. package/lib/modules/Order/types.d.ts +6 -1
  85. package/lib/modules/Order/utils/virtualSettlement.d.ts +56 -0
  86. package/lib/modules/Order/utils/virtualSettlement.js +300 -0
  87. package/lib/modules/Order/utils.js +65 -21
  88. package/lib/modules/Payment/types.d.ts +2 -0
  89. package/lib/modules/Payment/utils.js +5 -1
  90. package/lib/modules/Payment/walletpass.d.ts +11 -0
  91. package/lib/modules/Payment/walletpass.js +198 -17
  92. package/lib/modules/Product/types.d.ts +23 -0
  93. package/lib/modules/ProductList/index.d.ts +15 -2
  94. package/lib/modules/ProductList/index.js +85 -3
  95. package/lib/modules/ResourcePlanner/index.d.ts +0 -22
  96. package/lib/modules/ResourcePlanner/index.js +0 -123
  97. package/lib/modules/ResourcePlanner/localClock.d.ts +33 -0
  98. package/lib/modules/ResourcePlanner/localClock.js +270 -0
  99. package/lib/modules/ResourcePlanner/planner.d.ts +5 -14
  100. package/lib/modules/ResourcePlanner/planner.js +1903 -798
  101. package/lib/modules/ResourcePlanner/types.d.ts +346 -187
  102. package/lib/modules/ResourcePlanner/types.js +19 -0
  103. package/lib/modules/SalesSummary/index.d.ts +1 -0
  104. package/lib/modules/SalesSummary/index.js +10 -2
  105. package/lib/modules/SalesSummary/types.d.ts +1 -0
  106. package/lib/modules/SalesSummary/utils.d.ts +1 -0
  107. package/lib/modules/SalesSummary/utils.js +25 -1
  108. package/lib/server/index.d.ts +9 -0
  109. package/lib/server/index.js +54 -14
  110. package/lib/server/modules/order/index.d.ts +1 -0
  111. package/lib/server/modules/order/index.js +66 -2
  112. package/lib/server/utils/small-ticket.js +1 -1
  113. package/lib/solution/BaseSales/index.d.ts +26 -2
  114. package/lib/solution/BaseSales/index.js +261 -23
  115. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.d.ts +1 -0
  116. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +61 -11
  117. package/lib/solution/BookingByStep/index.d.ts +4 -4
  118. package/lib/solution/BookingTicket/index.d.ts +5 -1
  119. package/lib/solution/BookingTicket/index.js +32 -3
  120. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +2 -1
  121. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -1
  122. package/lib/solution/ScanOrder/index.js +17 -54
  123. package/lib/solution/UnifiedBookingSales/index.d.ts +110 -73
  124. package/lib/solution/UnifiedBookingSales/index.js +2289 -374
  125. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.d.ts +49 -0
  126. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +376 -0
  127. package/lib/solution/UnifiedBookingSales/types.d.ts +133 -76
  128. package/lib/solution/UnifiedBookingSales/types.js +3 -2
  129. package/package.json +1 -1
@@ -1,91 +1,163 @@
1
- import type { ResourcePlannerModule } from '../../modules';
2
1
  import type { OpenDataConfig } from '../../modules/OpenData';
3
- import type { ResourcePlannerAssignment, ResourcePlannerAssignableSlotResult, ResourcePlannerContextInput, ResourcePlannerProjection, ResourcePlannerQuery, ResourcePlannerSelectionPatch, ResourcePlannerSnapshot, ResourcePlannerValidationResult } from '../../modules/ResourcePlanner';
4
2
  import type { ProductListLoadProductsParams } from '../../modules/ProductList';
5
3
  import type { LoadScheduleAvailableDateParams } from '../../modules/Schedule/types';
4
+ import type { AvailabilityDateRange, AvailabilityErrorCode, AvailabilityId, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProjection, AvailabilityQuery, AvailabilityRequirementSelection, AvailabilityResource, AvailabilitySelectionValidationResult, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, ResourceAvailabilityGroup, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem } from '../../modules/ResourcePlanner';
6
5
  import type { BookingTicketState } from '../BookingTicket/types';
7
- export declare enum UnifiedBookingSalesHooks {
8
- onPlannerContextLoaded = "unifiedBookingSales:onPlannerContextLoaded",
9
- onPlannerCommitted = "unifiedBookingSales:onPlannerCommitted"
10
- }
6
+ export type { AvailabilityAbsoluteRange, AvailabilityAssignment, AvailabilityCell, AvailabilityDateRange, AvailabilityDisplayRange, AvailabilityErrorCode, AvailabilityId, AvailabilityMode, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProductKind, AvailabilityProjection, AvailabilityProjectionInput, AvailabilityProjectionMeta, AvailabilityQuery, AvailabilityQueryResult, AvailabilityRequirementGroup, AvailabilityRequirementGroupResult, AvailabilityRequirementSelection, AvailabilityResource, AvailabilityResourceOption, AvailabilityResourceType, AvailabilityResourceWindow, AvailabilityScheduleMode, AvailabilityScheduleRef, AvailabilityScheduleRule, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, AvailabilitySessionRange, AvailabilityStatus, DateAvailabilityGroup, DateAvailabilityItem, DateAvailabilityQuery, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityGroup, ProductAvailabilityItem, ProductAvailabilityQuery, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, QueryAvailabilityBaseRequest, ResourceAvailabilityGroup, ResourceAvailabilityQuery, ResourceAvailabilityQueryResult, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem, TimeAvailabilityQuery, TimeAvailabilityQueryResult, } from '../../modules/ResourcePlanner';
11
7
  export interface UnifiedBookingSalesState extends BookingTicketState {
12
- resourcePlanner: ResourcePlannerModule;
8
+ }
9
+ export declare enum UnifiedBookingSalesHooks {
10
+ onAvailabilityProjectionPrepared = "unifiedBookingSales:onAvailabilityProjectionPrepared",
11
+ onAvailabilitySelectionCommitted = "unifiedBookingSales:onAvailabilitySelectionCommitted",
12
+ onAvailabilityProjectionDiagnostic = "unifiedBookingSales:onAvailabilityProjectionDiagnostic"
13
13
  }
14
14
  export interface UnifiedBookingSalesOtherParams extends Record<string, any> {
15
- /**
16
- * Persist the active order workspace in sessionStorage, partitioned by cacheId.
17
- * Disabled by default and ignored when cacheId is missing.
18
- */
19
15
  enableSessionStoragePersist?: boolean;
20
16
  }
21
- /** Explicit OpenData target used by page-level UnifiedBookingSales skins. */
22
17
  export interface UnifiedBookingSalesLoadOpenDataParams {
23
18
  businessCode: string;
24
19
  channel: string;
25
- /** Bypasses the target-scoped in-memory cache. */
26
20
  force?: boolean;
27
21
  }
28
- export interface UnifiedBookingSalesLoadPlannerContextParams extends ResourcePlannerQuery {
29
- /** ProductList request options used only when products are not supplied as raw/context data. */
30
- productLoadParams?: ProductListLoadProductsParams;
31
- /** Escape hatch for tests or callers that already own raw ProductList records. */
32
- rawProducts?: Record<string, any>[];
33
- /** Escape hatch for tests or callers that already own raw resource records. */
34
- rawResources?: Record<string, any>[];
35
- /** Fully normalized Planner context; takes precedence over API loading for supplied fields. */
36
- context?: ResourcePlannerContextInput;
37
- /** Enables the v2 resource API + schedule materialization path. */
38
- useResourceDateApi?: boolean;
39
- }
40
- export interface UnifiedBookingSalesCommitPlannerSelectionParams {
41
- /** Optional selection patch applied before validation and order mutation. */
42
- selection?: ResourcePlannerSelectionPatch;
43
- /** Directly supplies selected resource/time facts, usually from resolveAssignableSlots(). */
44
- assignments?: ResourcePlannerAssignment[];
45
- /** Defaults to false. True performs the real BaseSales / OrderModule submit after tempOrder is written. */
46
- submitAfterCommit?: boolean;
47
- }
48
22
  export interface UnifiedBookingSalesLoadProductsByScheduleDateParams extends Omit<ProductListLoadProductsParams, 'schedule_date' | 'product_ids'> {
49
- /** The chosen calendar date, used for both availability lookup and ProductList schedule_date. */
50
23
  date: string;
51
- /** Optional caller-side filter applied after the availability result produces its product pool. */
52
24
  product_ids?: number[];
53
- /** Required by the availability API; this is not the low-code page id. */
54
25
  custom_page_id?: number;
55
- /** Availability API channel, commonly pc. ProductList keeps its own sales application channel. */
56
26
  channel?: string;
57
27
  }
58
- export interface UnifiedBookingSalesStagePlannerProductsParams {
59
- /** Products the customer selected before a time/resource booking exists. */
28
+ export type UnifiedBookingSalesCatalogScope = {
29
+ type: 'schedule';
30
+ customPageId: number;
31
+ channel: string;
32
+ } | {
33
+ type: 'productList';
34
+ params: ProductListLoadProductsParams;
35
+ };
36
+ export interface UnifiedBookingSalesPrepareAvailabilityProjectionParams {
37
+ productIds?: number[];
38
+ resourceIds?: AvailabilityId[];
39
+ dateRange?: Partial<AvailabilityDateRange>;
40
+ catalogScope?: UnifiedBookingSalesCatalogScope;
41
+ rawProducts?: Record<string, any>[];
42
+ rawResources?: Record<string, any>[];
43
+ rawOccupancies?: AvailabilityOccupancy[];
44
+ editingProductLineUids?: string[];
45
+ timezone?: string;
46
+ slotStepMinutes?: number;
47
+ businessHours?: {
48
+ startTime: string;
49
+ endTime: string;
50
+ };
51
+ mode?: 'appointment' | 'scan_order' | 'venue_grid';
52
+ }
53
+ export interface AvailabilityContextRef {
54
+ contextId: string;
55
+ }
56
+ export interface ContextualProductTimeRange extends ProductTimeRange {
57
+ availabilityContextId: string;
58
+ availabilityContextVersion: number;
59
+ }
60
+ export interface ContextualProductTimeRangeGroup extends Omit<ProductTimeRangeGroup, 'ranges'> {
61
+ ranges: ContextualProductTimeRange[];
62
+ }
63
+ export type ContextualAvailabilityQuery = Omit<Extract<AvailabilityQuery, {
64
+ target: 'product';
65
+ }>, never> | Omit<Extract<AvailabilityQuery, {
66
+ target: 'date';
67
+ }>, never> | (Omit<Extract<AvailabilityQuery, {
68
+ target: 'time';
69
+ }>, 'candidates'> & {
70
+ candidates: ContextualProductTimeRange[];
71
+ }) | (Omit<Extract<AvailabilityQuery, {
72
+ target: 'resource';
73
+ }>, 'selectedRanges'> & {
74
+ selectedRanges: ContextualProductTimeRange[];
75
+ });
76
+ export type ContextualTimeAvailabilityItem = Omit<TimeAvailabilityItem, keyof ProductTimeRange> & ContextualProductTimeRange;
77
+ export interface ContextualTimeAvailabilityGroup extends Omit<TimeAvailabilityGroup, 'times'> {
78
+ times: ContextualTimeAvailabilityItem[];
79
+ }
80
+ export interface ContextualResourceAvailabilityRangeGroup extends Omit<ResourceAvailabilityRangeGroup, 'range'> {
81
+ range: ContextualProductTimeRange;
82
+ }
83
+ export interface ContextualResourceAvailabilityGroup extends Omit<ResourceAvailabilityGroup, 'ranges'> {
84
+ ranges: ContextualResourceAvailabilityRangeGroup[];
85
+ }
86
+ type ContextualAvailabilityQueryResultMeta = {
87
+ contextId: string;
88
+ contextVersion: number;
89
+ refreshed: boolean;
90
+ };
91
+ export type ContextualAvailabilityQueryResult = (ProductAvailabilityQueryResult & ContextualAvailabilityQueryResultMeta) | (DateAvailabilityQueryResult & ContextualAvailabilityQueryResultMeta) | ({
92
+ target: 'time';
93
+ evaluatedAt: string;
94
+ snapshotId: string;
95
+ data: ContextualTimeAvailabilityGroup[];
96
+ } & ContextualAvailabilityQueryResultMeta) | ({
97
+ target: 'resource';
98
+ evaluatedAt: string;
99
+ snapshotId: string;
100
+ data: ContextualResourceAvailabilityGroup[];
101
+ } & ContextualAvailabilityQueryResultMeta);
102
+ export type UnifiedBookingSalesAvailabilityCandidate = ContextualProductTimeRange;
103
+ export type UnifiedBookingSalesProductTimeRangeGroup = ContextualProductTimeRangeGroup;
104
+ export type UnifiedBookingSalesAvailabilityQueryResult = ContextualAvailabilityQueryResult;
105
+ export interface UnifiedBookingSalesAvailabilityPreparedPayload {
106
+ context: AvailabilityContextRef;
107
+ contextVersion: number;
108
+ projection: AvailabilityProjection;
109
+ refreshed: boolean;
110
+ reason?: string;
111
+ previousOrderRevision?: AvailabilityId;
112
+ }
113
+ export interface UnifiedBookingSalesAvailabilityDiagnosticPayload {
114
+ contextId: string | null;
115
+ contextVersion: number | null;
116
+ reason: string;
117
+ projection: AvailabilityProjection | null;
118
+ action: 'prepare' | 'refresh' | 'release' | 'destroy' | 'set_other_params_reset' | 'commit_lock_wait' | 'commit_lock_acquired' | 'commit_lock_released';
119
+ snapshotId?: string;
120
+ orderRevision?: AvailabilityId;
121
+ previousOrderRevision?: AvailabilityId;
122
+ registrySize: number;
123
+ projectionPoolSize: number;
124
+ }
125
+ export interface UnifiedBookingSalesStageRetailProductsParams {
60
126
  productIds: Array<number | string>;
61
127
  productLoadParams?: ProductListLoadProductsParams;
62
128
  rawProducts?: Record<string, any>[];
63
129
  }
64
- /** Ordinary retail product staging. No resource, time, or booking facts are required. */
65
- export type UnifiedBookingSalesStageRetailProductsParams = UnifiedBookingSalesStagePlannerProductsParams;
66
- /** Adds one ordinary retail product without replacing other retail lines already in the cart. */
67
130
  export interface UnifiedBookingSalesAddRetailProductParams {
68
- /** Prefer a supplied catalog record when the UI has already loaded it. */
69
131
  product?: Record<string, any>;
70
- /** Used to resolve a product from the current catalog or load it on demand. */
71
132
  productId?: number | string;
72
- /** Defaults to one. */
73
133
  quantity?: number;
74
- /** Only used when the product is not already present in the solution catalog. */
75
134
  productLoadParams?: ProductListLoadProductsParams;
76
135
  }
77
- export interface UnifiedBookingSalesCommitResult {
136
+ export interface ContextualCommitAvailabilitySelectionParams {
137
+ mode: 'add' | 'edit';
138
+ productLineUid?: string;
139
+ orderProduct: Record<string, any>;
140
+ candidate: ContextualProductTimeRange;
141
+ requirementSelections: AvailabilityRequirementSelection[];
142
+ partySize: number;
143
+ bookingCount?: number;
144
+ }
145
+ export type UnifiedBookingSalesCommitAvailabilitySelectionParams = ContextualCommitAvailabilitySelectionParams;
146
+ export interface UnifiedBookingSalesCommitAvailabilitySelectionResult {
147
+ contextId: string;
148
+ contextVersion: number;
78
149
  tempOrder: Record<string, any> | null;
79
- assignments: ResourcePlannerAssignment[];
80
- validation: ResourcePlannerValidationResult;
81
- submitResult?: unknown;
150
+ validation: AvailabilitySelectionValidationResult;
151
+ candidate: ContextualProductTimeRange;
152
+ productLineUid?: string;
153
+ bookingUid?: string;
154
+ productLineUids?: string[];
155
+ bookingUids?: string[];
82
156
  }
157
+ export type UnifiedBookingSalesAvailabilityErrorCode = AvailabilityErrorCode;
83
158
  export interface UnifiedBookingSalesApplyPlannerDiscountsParams {
84
- /** Customer whose cards/coupons should be loaded. Defaults to tempOrder.customer_id. */
85
159
  customerId?: number | string;
86
- /** Optional explicit card/coupon id. When provided, Rules applies this card instead of auto-picking another card. */
87
160
  preferredDiscountId?: number | string;
88
- /** Defaults to true: after loading eligible cards, let Rules choose the best valid combination. */
89
161
  applyBestDiscount?: boolean;
90
162
  }
91
163
  export interface UnifiedBookingSalesDiscountItem {
@@ -110,7 +182,6 @@ export interface UnifiedBookingSalesDiscountResult {
110
182
  status: 'applied' | 'loaded' | 'no_customer';
111
183
  customerId: number | null;
112
184
  preferredDiscountFound?: boolean;
113
- /** True only when the requested card is both selected and written into a planner product line. */
114
185
  preferredDiscountApplied?: boolean;
115
186
  availableDiscounts: UnifiedBookingSalesDiscountItem[];
116
187
  selectedDiscounts: UnifiedBookingSalesDiscountItem[];
@@ -119,32 +190,18 @@ export interface UnifiedBookingSalesDiscountResult {
119
190
  summaryAfter?: unknown;
120
191
  }
121
192
  export interface UnifiedBookingSalesApi {
122
- /** Loads board OpenData for a concrete business + channel target. */
123
193
  loadOpenData: (params: UnifiedBookingSalesLoadOpenDataParams) => Promise<OpenDataConfig>;
124
- /** Returns the latest OpenData payload cached by this solution instance. */
125
- getOpenData: () => OpenDataConfig | null;
126
- /** Date-first calendar availability backed by ScheduleModule. */
194
+ getOpenData: () => Promise<OpenDataConfig | null>;
127
195
  loadScheduleAvailableDate: (params: LoadScheduleAvailableDateParams) => Promise<unknown>;
128
- /** Date-first product pool derived from schedule date ids and globally sellable products. */
129
196
  loadProductsByScheduleDate: (params: UnifiedBookingSalesLoadProductsByScheduleDateParams) => Promise<unknown[]>;
130
- /** Adds product lines only; booking creation is intentionally deferred. */
131
- stagePlannerProducts: (params: UnifiedBookingSalesStagePlannerProductsParams) => Promise<Record<string, any> | null>;
132
- /** Adds ordinary product lines only. It never creates bookings or invokes ResourcePlanner. */
133
197
  stageRetailProducts: (params: UnifiedBookingSalesStageRetailProductsParams) => Promise<Record<string, any> | null>;
134
- /** Adds one ordinary retail line while preserving all existing cart lines. */
135
198
  addRetailProduct: (params: UnifiedBookingSalesAddRetailProductParams) => Promise<Record<string, any>[]>;
136
- /** Loads and normalizes all IO data needed for the pure ResourcePlanner. */
137
- loadPlannerContext: (params?: UnifiedBookingSalesLoadPlannerContextParams) => Promise<ResourcePlannerSnapshot>;
138
- /** Reads continuous availability cells and UI-oriented aggregates. */
139
- queryPlannerAvailability: (query?: ResourcePlannerQuery) => Promise<ResourcePlannerProjection>;
140
- /** Produces selectable slots and the assignments required to commit them. */
141
- resolveAssignableSlots: (query?: ResourcePlannerQuery) => ResourcePlannerAssignableSlotResult;
142
- setPlannerSelection: (patch: ResourcePlannerSelectionPatch) => ResourcePlannerSnapshot;
143
- autoAssignPlanner: (query?: ResourcePlannerQuery) => Promise<ResourcePlannerSnapshot>;
144
- validatePlannerSelection: () => ResourcePlannerValidationResult;
145
- /** Validates, writes to tempOrder, and only optionally makes a real submit request. */
146
- commitPlannerSelection: (params?: UnifiedBookingSalesCommitPlannerSelectionParams) => Promise<UnifiedBookingSalesCommitResult>;
147
- /** Loads the current customer's cards/coupons, optionally applies the best one, and reports line applications. */
199
+ prepareAvailabilityProjection: (params: UnifiedBookingSalesPrepareAvailabilityProjectionParams) => Promise<AvailabilityContextRef>;
200
+ getProductTimeRanges: (contextId: string, request?: GetProductTimeRangesRequest) => Promise<ContextualProductTimeRangeGroup[]>;
201
+ queryBookingAvailability: (contextId: string, request: ContextualAvailabilityQuery) => Promise<ContextualAvailabilityQueryResult>;
202
+ commitAvailabilitySelection: (contextId: string, params: ContextualCommitAvailabilitySelectionParams) => Promise<UnifiedBookingSalesCommitAvailabilitySelectionResult>;
203
+ releaseAvailabilityContext: (contextId: string) => void;
148
204
  applyPlannerDiscounts: (params?: UnifiedBookingSalesApplyPlannerDiscountsParams) => Promise<UnifiedBookingSalesDiscountResult>;
149
- getPlannerSnapshot: () => ResourcePlannerSnapshot;
150
205
  }
206
+ export type UnifiedBookingSalesNormalizedProduct = AvailabilityProduct;
207
+ export type UnifiedBookingSalesNormalizedResource = AvailabilityResource;
@@ -1,11 +1,6 @@
1
1
  export var UnifiedBookingSalesHooks = /*#__PURE__*/function (UnifiedBookingSalesHooks) {
2
- UnifiedBookingSalesHooks["onPlannerContextLoaded"] = "unifiedBookingSales:onPlannerContextLoaded";
3
- UnifiedBookingSalesHooks["onPlannerCommitted"] = "unifiedBookingSales:onPlannerCommitted";
2
+ UnifiedBookingSalesHooks["onAvailabilityProjectionPrepared"] = "unifiedBookingSales:onAvailabilityProjectionPrepared";
3
+ UnifiedBookingSalesHooks["onAvailabilitySelectionCommitted"] = "unifiedBookingSales:onAvailabilitySelectionCommitted";
4
+ UnifiedBookingSalesHooks["onAvailabilityProjectionDiagnostic"] = "unifiedBookingSales:onAvailabilityProjectionDiagnostic";
4
5
  return UnifiedBookingSalesHooks;
5
- }({});
6
-
7
- /** Explicit OpenData target used by page-level UnifiedBookingSales skins. */
8
-
9
- /** Ordinary retail product staging. No resource, time, or booking facts are required. */
10
-
11
- /** Adds one ordinary retail product without replacing other retail lines already in the cart. */
6
+ }({});
package/lib/core/index.js CHANGED
@@ -50,7 +50,6 @@ var PisellOSCore = class {
50
50
  this.serverOptions = options.server;
51
51
  }
52
52
  this.initialize(options);
53
- console.log("constructor1234");
54
53
  }
55
54
  initialize(options) {
56
55
  if (options == null ? void 0 : options.plugins) {
@@ -3,7 +3,7 @@ import type { ConditionScope, DataVariantBusinessData, DataVariantMenu, DataVari
3
3
  /**
4
4
  * Data Variant 评估器。
5
5
  *
6
- * 当前阶段只提供策略模型能力和示例验证,不接入 ProductList 业务链路。
6
+ * OS Server 商品路由开启时由 ProductsModule 调用;路由关闭时由 ProductList 在远端响应后调用。
7
7
  */
8
8
  export declare class DataVariantEvaluator {
9
9
  private adapter;
@@ -17,7 +17,7 @@ export declare class DataVariantEvaluator {
17
17
  /**
18
18
  * 批量解析商品 Data Variant。
19
19
  *
20
- * 先执行全局预计算,再只针对商品自身 data_variants 引用到的规则做商品级判断。
20
+ * 优先使用商品 metadata.data_variant_ids;缺少权威命中结果时才执行本地策略判断。
21
21
  */
22
22
  resolveProducts(businessData: DataVariantBusinessData): ResolvedDataVariantResult;
23
23
  /**
@@ -34,8 +34,24 @@ export declare class DataVariantEvaluator {
34
34
  * 这里不依赖餐牌,只读取策略配置和调用方传入的 scheduleList。
35
35
  */
36
36
  buildScheduleTimePoints(strategyConfigs: StrategyConfig<DataVariantRuleMetadata>[], scheduleList: NonNullable<DataVariantBusinessData['scheduleList']>): string[];
37
+ /**
38
+ * 判断商品(含套餐子商品)是否仍需要本地执行策略条件。
39
+ * metadata.data_variant_ids 只要是数组,即使为空,也表示接口已经给出权威命中结果。
40
+ */
41
+ private requiresLocalStrategyEvaluation;
42
+ /**
43
+ * 将接口返回的高 -> 低优先级 Variant ID 转成数值优先级。
44
+ * 返回 null 表示接口没有提供该字段;空 Map 表示已计算但没有任何命中。
45
+ */
46
+ private getAuthoritativeVariantPriorities;
47
+ private normalizeDataVariantId;
37
48
  private buildGlobalEffectiveRuleMap;
38
49
  private resolveProduct;
50
+ /**
51
+ * 多货币 Data Variant 只生成候选列表,不参与商品字段覆盖。
52
+ * rule_id=0 是无条件默认价;同币种命中的条件价优先于默认价。
53
+ */
54
+ private resolveSettlementOptions;
39
55
  /**
40
56
  * 解析套餐子商品上的 Data Variant 覆盖。
41
57
  *
@@ -43,7 +43,7 @@ var DataVariantEvaluator = class {
43
43
  /**
44
44
  * 批量解析商品 Data Variant。
45
45
  *
46
- * 先执行全局预计算,再只针对商品自身 data_variants 引用到的规则做商品级判断。
46
+ * 优先使用商品 metadata.data_variant_ids;缺少权威命中结果时才执行本地策略判断。
47
47
  */
48
48
  resolveProducts(businessData) {
49
49
  const strategyConfigs = businessData.strategyConfigs ? this.normalizeStrategyConfigs(businessData.strategyConfigs) : this.strategyConfigs;
@@ -52,11 +52,17 @@ var DataVariantEvaluator = class {
52
52
  strategyConfigs,
53
53
  businessData.scheduleList || []
54
54
  );
55
- const { globalEffectiveRuleMap, rawResults } = this.buildGlobalEffectiveRuleMap(
55
+ const shouldEvaluateStrategies = businessData.products.some(
56
+ (product) => this.requiresLocalStrategyEvaluation(product)
57
+ );
58
+ const { globalEffectiveRuleMap, rawResults } = shouldEvaluateStrategies ? this.buildGlobalEffectiveRuleMap(
56
59
  strategyConfigs,
57
60
  businessData,
58
61
  menuScopeMap
59
- );
62
+ ) : {
63
+ globalEffectiveRuleMap: /* @__PURE__ */ new Map(),
64
+ rawResults: []
65
+ };
60
66
  const products = businessData.products.map((product) => {
61
67
  const resolvedProduct = this.resolveProduct(
62
68
  product,
@@ -154,6 +160,56 @@ var DataVariantEvaluator = class {
154
160
  );
155
161
  return this.extractTimePointsFromSchedules(matchedSchedules);
156
162
  }
163
+ /**
164
+ * 判断商品(含套餐子商品)是否仍需要本地执行策略条件。
165
+ * metadata.data_variant_ids 只要是数组,即使为空,也表示接口已经给出权威命中结果。
166
+ */
167
+ requiresLocalStrategyEvaluation(product) {
168
+ const dataVariants = this.getProductDataVariants(product);
169
+ const hasConditionalVariant = dataVariants.some(
170
+ (variant) => Number(variant.data_variant_rule_id) !== 0
171
+ );
172
+ if (hasConditionalVariant && this.getAuthoritativeVariantPriorities(product) === null) {
173
+ return true;
174
+ }
175
+ const bundleGroups = Array.isArray(product.bundle_group) ? product.bundle_group : [];
176
+ return bundleGroups.some((group) => {
177
+ const bundleItems = Array.isArray(group == null ? void 0 : group.bundle_item) ? group.bundle_item : [];
178
+ return bundleItems.some(
179
+ (item) => this.requiresLocalStrategyEvaluation(
180
+ this.toBundleItemDataVariantProduct(item)
181
+ )
182
+ );
183
+ });
184
+ }
185
+ /**
186
+ * 将接口返回的高 -> 低优先级 Variant ID 转成数值优先级。
187
+ * 返回 null 表示接口没有提供该字段;空 Map 表示已计算但没有任何命中。
188
+ */
189
+ getAuthoritativeVariantPriorities(product) {
190
+ var _a;
191
+ const rawIds = (_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.data_variant_ids;
192
+ if (!Array.isArray(rawIds))
193
+ return null;
194
+ const orderedIds = [];
195
+ const seen = /* @__PURE__ */ new Set();
196
+ for (const rawId of rawIds) {
197
+ const id = this.normalizeDataVariantId(rawId);
198
+ if (id === null || seen.has(id))
199
+ continue;
200
+ seen.add(id);
201
+ orderedIds.push(id);
202
+ }
203
+ return new Map(
204
+ orderedIds.map((id, index) => [id, orderedIds.length - index])
205
+ );
206
+ }
207
+ normalizeDataVariantId(value) {
208
+ if (value === void 0 || value === null)
209
+ return null;
210
+ const normalized = String(value).trim();
211
+ return normalized || null;
212
+ }
157
213
  buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) {
158
214
  const globalEffectiveRuleMap = /* @__PURE__ */ new Map();
159
215
  const rawResults = [];
@@ -182,7 +238,26 @@ var DataVariantEvaluator = class {
182
238
  if (!dataVariants.length)
183
239
  return product;
184
240
  const matchedVariants = [];
241
+ const authoritativeVariantPriorities = this.getAuthoritativeVariantPriorities(product);
242
+ const settlementVariants = dataVariants.filter(
243
+ (variant) => variant.business_type === "multi_currency_settlement" && variant.status === "enable"
244
+ );
185
245
  for (const variant of dataVariants) {
246
+ if (variant.business_type === "multi_currency_settlement")
247
+ continue;
248
+ if (authoritativeVariantPriorities !== null) {
249
+ const variantId = this.normalizeDataVariantId(variant.id);
250
+ const priority = variantId === null ? void 0 : authoritativeVariantPriorities.get(variantId);
251
+ if (priority === void 0)
252
+ continue;
253
+ matchedVariants.push({
254
+ ruleId: String(variant.data_variant_rule_id),
255
+ priority,
256
+ data: variant.data || {},
257
+ variant
258
+ });
259
+ continue;
260
+ }
186
261
  const rule = globalEffectiveRuleMap.get(
187
262
  String(variant.data_variant_rule_id)
188
263
  );
@@ -198,9 +273,91 @@ var DataVariantEvaluator = class {
198
273
  variant
199
274
  });
200
275
  }
201
- if (!matchedVariants.length)
202
- return product;
203
- return this.mergeMatchedVariants(product, matchedVariants);
276
+ const resolvedProduct = matchedVariants.length ? this.mergeMatchedVariants(product, matchedVariants) : product;
277
+ const availableSettlementOptions = this.resolveSettlementOptions(
278
+ settlementVariants,
279
+ product,
280
+ businessData,
281
+ globalEffectiveRuleMap,
282
+ menuScopeMap,
283
+ authoritativeVariantPriorities
284
+ );
285
+ if (!settlementVariants.length)
286
+ return resolvedProduct;
287
+ return {
288
+ ...resolvedProduct,
289
+ available_settlement_options: availableSettlementOptions
290
+ };
291
+ }
292
+ /**
293
+ * 多货币 Data Variant 只生成候选列表,不参与商品字段覆盖。
294
+ * rule_id=0 是无条件默认价;同币种命中的条件价优先于默认价。
295
+ */
296
+ resolveSettlementOptions(variants, product, businessData, globalEffectiveRuleMap, menuScopeMap, authoritativeVariantPriorities) {
297
+ if (!variants.length)
298
+ return [];
299
+ const candidates = variants.flatMap((variant) => {
300
+ var _a, _b;
301
+ const settlement = (_a = variant.data) == null ? void 0 : _a.multi_currency_settlement;
302
+ if (!settlement || typeof settlement !== "object")
303
+ return [];
304
+ const ruleId = String(variant.data_variant_rule_id);
305
+ const isDefault = Number(variant.data_variant_rule_id) === 0;
306
+ const rule = isDefault ? void 0 : globalEffectiveRuleMap.get(ruleId);
307
+ const variantId = this.normalizeDataVariantId(variant.id);
308
+ const authoritativePriority = variantId === null ? void 0 : authoritativeVariantPriorities == null ? void 0 : authoritativeVariantPriorities.get(variantId);
309
+ let available;
310
+ let priority;
311
+ if (isDefault) {
312
+ available = true;
313
+ priority = Number.NEGATIVE_INFINITY;
314
+ } else if (authoritativeVariantPriorities !== null) {
315
+ available = authoritativePriority !== void 0;
316
+ priority = authoritativePriority ?? (rule == null ? void 0 : rule.priority) ?? Number.NEGATIVE_INFINITY;
317
+ } else {
318
+ available = Boolean(
319
+ rule && this.evaluateProductRules(
320
+ rule,
321
+ product,
322
+ businessData,
323
+ menuScopeMap
324
+ )
325
+ );
326
+ priority = (rule == null ? void 0 : rule.priority) ?? Number.NEGATIVE_INFINITY;
327
+ }
328
+ const settlementType = String(settlement.settlement_type || "");
329
+ const currencyProductId = this.toNumber(settlement.currency_product_id);
330
+ const settlementKey = settlementType === "virtual_currency" ? `virtual_currency:${currencyProductId || ""}` : settlementType || `variant:${variant.id ?? ruleId}`;
331
+ return [{
332
+ key: settlementKey,
333
+ priority,
334
+ isDefault,
335
+ option: {
336
+ ...settlement,
337
+ settlement_type: settlementType,
338
+ ...currencyProductId ? { currency_product_id: currencyProductId } : {},
339
+ price: String(((_b = variant.data) == null ? void 0 : _b.price) ?? "0"),
340
+ data_variant_id: variant.id,
341
+ data_variant_rule_id: variant.data_variant_rule_id,
342
+ available,
343
+ disabled_reason: available ? "" : String(
344
+ settlement.disabled_reason || "Not available for this purchase."
345
+ )
346
+ }
347
+ }];
348
+ });
349
+ const grouped = /* @__PURE__ */ new Map();
350
+ for (const candidate of candidates) {
351
+ const group = grouped.get(candidate.key) || [];
352
+ group.push(candidate);
353
+ grouped.set(candidate.key, group);
354
+ }
355
+ return Array.from(grouped.values()).map((group) => {
356
+ const matchedConditional = group.filter((candidate) => !candidate.isDefault && candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
357
+ const defaultCandidate = group.find((candidate) => candidate.isDefault);
358
+ const unavailableCandidate = [...group].filter((candidate) => !candidate.option.available).sort((a, b) => b.priority - a.priority)[0];
359
+ return (matchedConditional || defaultCandidate || unavailableCandidate).option;
360
+ });
204
361
  }
205
362
  /**
206
363
  * 解析套餐子商品上的 Data Variant 覆盖。
@@ -262,7 +419,8 @@ var DataVariantEvaluator = class {
262
419
  product_variant_id: variantId,
263
420
  variant_id: variantId,
264
421
  collection: item.collection,
265
- data_variants: item.data_variants
422
+ data_variants: item.data_variants,
423
+ metadata: item.metadata
266
424
  };
267
425
  }
268
426
  /**
@@ -501,6 +659,11 @@ var DataVariantEvaluator = class {
501
659
  }
502
660
  result._dataVariant = {
503
661
  appliedRuleIds,
662
+ appliedVariantIds: Array.from(
663
+ new Set(
664
+ [...sortedVariants].reverse().map((matched) => this.normalizeDataVariantId(matched.variant.id)).filter((id) => id !== null)
665
+ )
666
+ ),
504
667
  appliedFields: Array.from(appliedFields),
505
668
  original
506
669
  };
@@ -35,6 +35,10 @@ export interface DataVariantItem {
35
35
  module_data_id?: number;
36
36
  /** 关联策略模型 metadata.id / data_variant_rule.id */
37
37
  data_variant_rule_id: number | string;
38
+ /** 业务类型;多货币结算候选不会走普通字段覆盖 */
39
+ business_type?: 'multi_currency_settlement' | string;
40
+ /** 数据状态;多货币结算仅处理 enable 记录 */
41
+ status?: 'enable' | 'disable' | string;
38
42
  /** 命中策略后需要覆盖到商品上的字段 */
39
43
  data: Record<string, any>;
40
44
  created_at?: string | null;
@@ -53,11 +57,30 @@ export interface DataVariantProduct {
53
57
  id?: number | string;
54
58
  [key: string]: any;
55
59
  }>;
60
+ /**
61
+ * 商品接口已经完成规则计算时返回的命中结果。
62
+ * 数组按 Data Variant 优先级从高到低排列;空数组表示已计算但无命中。
63
+ */
64
+ metadata?: {
65
+ data_variant_ids?: Array<number | string>;
66
+ [key: string]: any;
67
+ };
56
68
  /** 后端 /product/query with dataVariants 返回的智能定价变体列表 */
57
69
  data_variants?: DataVariantItem[];
70
+ /** 当前上下文解析后的可选结算货币,不覆盖商品原始多货币配置 */
71
+ available_settlement_options?: AvailableSettlementOption[];
58
72
  _dataVariant?: DataVariantAppliedInfo;
59
73
  [key: string]: any;
60
74
  }
75
+ export interface AvailableSettlementOption extends Record<string, any> {
76
+ settlement_type: 'legal_currency' | 'virtual_currency' | string;
77
+ currency_product_id?: number;
78
+ price: string;
79
+ data_variant_id?: number;
80
+ data_variant_rule_id: number | string;
81
+ available: boolean;
82
+ disabled_reason?: string;
83
+ }
61
84
  /**
62
85
  * 餐牌商品配置项。
63
86
  */
@@ -131,6 +154,8 @@ export interface MatchedDataVariant {
131
154
  */
132
155
  export interface DataVariantAppliedInfo {
133
156
  appliedRuleIds: string[];
157
+ /** 本地策略实际应用的 Data Variant ID,按优先级从高到低排列。 */
158
+ appliedVariantIds?: Array<number | string>;
134
159
  appliedFields: string[];
135
160
  original: DataVariantProduct;
136
161
  }
@@ -214,7 +214,6 @@ var WalletPassEvaluator = class {
214
214
  }
215
215
  const rawText = this.getText(reasonCode);
216
216
  const currency = failedField && AMOUNT_FIELDS.has(failedField) ? ((_g = (_f = this.otherParams) == null ? void 0 : _f.getData) == null ? void 0 : _g.call(_f, "shop_symbol")) || "" : "";
217
- console.log(currency, "currency12345");
218
217
  const reason = thresholdValue !== void 0 ? formatReason(rawText, thresholdValue, currency) : rawText;
219
218
  results.push({
220
219
  voucher,
@@ -416,7 +415,6 @@ var WalletPassEvaluator = class {
416
415
  * 计算适用商品的总金额和数量
417
416
  */
418
417
  calculateApplicableProducts(products, applicableProductIds, deductTaxAndFee) {
419
- console.log(products, "products1234");
420
418
  let total = 0;
421
419
  let count = 0;
422
420
  if (applicableProductIds !== null && applicableProductIds.length === 0) {
@@ -26,6 +26,11 @@ export interface Voucher {
26
26
  recommended_usage_amount: number;
27
27
  /** 后端计算推荐使用金额(仅商品) 不包含税费附加费 */
28
28
  recommended_pure_product_usage_amount: number;
29
+ /**
30
+ * 扫码资产自身可供前端重新计算的金额基准。
31
+ * 后端 recommended_usage_amount 会包含当前已选券上下文,取消勾选后不能继续把它当作资产永久上限。
32
+ */
33
+ _wallet_asset_recalculation_base_amount?: number;
29
34
  /** 实际抵扣金额 */
30
35
  actualDeduction: number;
31
36
  /** 抵扣详情 */