@pisell/pisellos 2.2.298 → 2.2.300
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.
- package/dist/modules/ResourcePlanner/planner.d.ts +2 -2
- package/dist/modules/ResourcePlanner/planner.js +160 -44
- package/dist/modules/ResourcePlanner/types.d.ts +12 -0
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/UnifiedBookingSales/index.js +88 -19
- package/lib/modules/ResourcePlanner/planner.d.ts +2 -2
- package/lib/modules/ResourcePlanner/planner.js +129 -30
- package/lib/modules/ResourcePlanner/types.d.ts +12 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/UnifiedBookingSales/index.js +80 -20
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AvailabilityProjection, AvailabilityProjectionInput, AvailabilityQuery, AvailabilityQueryResult, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, GetProductTimeRangesRequest, GetProductTimeRangesRuntimeOptions, ProductTimeRangeGroup } from './types';
|
|
2
2
|
export declare function createAvailabilityProjection(input: AvailabilityProjectionInput): AvailabilityProjection;
|
|
3
3
|
export declare function getProductTimeRanges(projection: AvailabilityProjection, request?: GetProductTimeRangesRequest, runtimeOptions?: GetProductTimeRangesRuntimeOptions): ProductTimeRangeGroup[];
|
|
4
|
-
export declare function queryAvailabilityProjection(projection: AvailabilityProjection, request: AvailabilityQuery): AvailabilityQueryResult;
|
|
5
|
-
export declare function validateAvailabilitySelection(projection: AvailabilityProjection, params: AvailabilitySelectionValidationParams): AvailabilitySelectionValidationResult;
|
|
4
|
+
export declare function queryAvailabilityProjection(projection: AvailabilityProjection, request: AvailabilityQuery, runtimeOptions?: GetProductTimeRangesRuntimeOptions): AvailabilityQueryResult;
|
|
5
|
+
export declare function validateAvailabilitySelection(projection: AvailabilityProjection, params: AvailabilitySelectionValidationParams, runtimeOptions?: GetProductTimeRangesRuntimeOptions): AvailabilitySelectionValidationResult;
|
|
@@ -175,8 +175,70 @@ function addLeadWindow(base, unit, unitType, _timezoneName) {
|
|
|
175
175
|
if (unitType === 'hours') return addLocalHours(base, unit);
|
|
176
176
|
return addLocalMinutes(base, unit);
|
|
177
177
|
}
|
|
178
|
+
function normalizedWindowContainsRange(windows, candidateRange, timezoneName) {
|
|
179
|
+
return windows.some(function (window) {
|
|
180
|
+
var normalized = normalizeAbsoluteRange(window, timezoneName);
|
|
181
|
+
return Boolean(normalized && contains(normalized, candidateRange));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function normalizedWindowsContainDate(windows, date, timezoneName) {
|
|
185
|
+
return windows.some(function (window) {
|
|
186
|
+
var normalized = normalizeAbsoluteRange(window, timezoneName);
|
|
187
|
+
return Boolean(normalized && formatDate(normalized.start, timezoneName) === date);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function isRangeFromExcludedWindows(params) {
|
|
191
|
+
var candidateDate = formatDate(params.candidateRange.start, params.timezoneName);
|
|
192
|
+
var hasNormalWindowOnDate = normalizedWindowsContainDate(params.normalWindows, candidateDate, params.timezoneName);
|
|
193
|
+
var hasExcludedWindowOnDate = normalizedWindowsContainDate(params.excludedWindows, candidateDate, params.timezoneName);
|
|
194
|
+
if (!hasNormalWindowOnDate && hasExcludedWindowOnDate) return true;
|
|
195
|
+
return !normalizedWindowContainsRange(params.normalWindows, params.candidateRange, params.timezoneName) && normalizedWindowContainsRange(params.excludedWindows, params.candidateRange, params.timezoneName);
|
|
196
|
+
}
|
|
197
|
+
function isCandidateFromExcludedScheduleDate(params) {
|
|
198
|
+
var projection = params.projection,
|
|
199
|
+
product = params.product,
|
|
200
|
+
candidate = params.candidate,
|
|
201
|
+
candidateRange = params.candidateRange;
|
|
202
|
+
var operatingHours = projection.meta.defaults.operatingHours;
|
|
203
|
+
if (isRangeFromExcludedWindows({
|
|
204
|
+
normalWindows: operatingHours.windows,
|
|
205
|
+
excludedWindows: operatingHours.excludedWindows || [],
|
|
206
|
+
candidateRange: candidateRange,
|
|
207
|
+
timezoneName: projection.meta.timezone
|
|
208
|
+
})) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
if (product.kind !== 'session' && product.kind !== 'venue_slot') {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (candidate.source !== 'session_schedule') {
|
|
215
|
+
var hasNormalRule = (product.sessionRules || []).some(function (rule) {
|
|
216
|
+
return matchesScheduleRuleDate(rule, candidate.date, projection.meta.timezone);
|
|
217
|
+
});
|
|
218
|
+
var hasExcludedOverrideRule = (product.sessionRules || []).some(function (rule) {
|
|
219
|
+
return !matchesScheduleRuleDate(rule, candidate.date, projection.meta.timezone) && matchesScheduleRuleDate(rule, candidate.date, projection.meta.timezone, true);
|
|
220
|
+
});
|
|
221
|
+
return !hasNormalRule && hasExcludedOverrideRule;
|
|
222
|
+
}
|
|
223
|
+
var candidateDateRange = {
|
|
224
|
+
startDate: candidate.date,
|
|
225
|
+
endDate: candidate.date
|
|
226
|
+
};
|
|
227
|
+
var candidateIdentity = getProductTimeRangeIdentity(candidate);
|
|
228
|
+
var normalRanges = getSessionRangesForProduct(projection, product, candidateDateRange);
|
|
229
|
+
if (normalRanges.some(function (range) {
|
|
230
|
+
return getProductTimeRangeIdentity(range) === candidateIdentity;
|
|
231
|
+
})) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
return getSessionRangesForProduct(projection, product, candidateDateRange, true).some(function (range) {
|
|
235
|
+
return getProductTimeRangeIdentity(range) === candidateIdentity;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
178
238
|
function evaluateCandidateTimeGate(params) {
|
|
179
|
-
var
|
|
239
|
+
var projection = params.projection,
|
|
240
|
+
product = params.product,
|
|
241
|
+
candidate = params.candidate,
|
|
180
242
|
candidateRange = params.candidateRange,
|
|
181
243
|
evaluationContext = params.evaluationContext,
|
|
182
244
|
timezoneName = params.timezoneName;
|
|
@@ -188,6 +250,18 @@ function evaluateCandidateTimeGate(params) {
|
|
|
188
250
|
conflictCode: 'past'
|
|
189
251
|
};
|
|
190
252
|
}
|
|
253
|
+
if (evaluationContext.allowExcludedScheduleDateOverride && isCandidateFromExcludedScheduleDate({
|
|
254
|
+
projection: projection,
|
|
255
|
+
product: product,
|
|
256
|
+
candidate: candidate,
|
|
257
|
+
candidateRange: candidateRange
|
|
258
|
+
})) {
|
|
259
|
+
return {
|
|
260
|
+
status: 'unavailable',
|
|
261
|
+
reasonCodes: ['schedule_excluded_date'],
|
|
262
|
+
conflictCode: 'schedule_excluded_date'
|
|
263
|
+
};
|
|
264
|
+
}
|
|
191
265
|
var policy = product.cutOffPolicy;
|
|
192
266
|
if (!policy) return null;
|
|
193
267
|
if (resolveCutOffPolicyIssue(policy)) {
|
|
@@ -334,7 +408,8 @@ function normalizeCoverage(input) {
|
|
|
334
408
|
};
|
|
335
409
|
}
|
|
336
410
|
function normalizeResourceWindow(resource, coverage, timezoneName) {
|
|
337
|
-
|
|
411
|
+
var includeExcludedWindows = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
412
|
+
return mergeRanges([].concat(_toConsumableArray(resource.windows || []), _toConsumableArray(includeExcludedWindows ? resource.excludedWindows || [] : [])).map(function (window) {
|
|
338
413
|
return normalizeAbsoluteRange(window, timezoneName);
|
|
339
414
|
}).filter(function (window) {
|
|
340
415
|
return Boolean(window);
|
|
@@ -407,12 +482,15 @@ function normalizeResources(resources) {
|
|
|
407
482
|
capacity: Math.max(1, Number(resource.capacity || 1) || 1),
|
|
408
483
|
windows: (resource.windows || []).map(function (window) {
|
|
409
484
|
return _objectSpread({}, window);
|
|
485
|
+
}),
|
|
486
|
+
excludedWindows: (resource.excludedWindows || []).map(function (window) {
|
|
487
|
+
return _objectSpread({}, window);
|
|
410
488
|
})
|
|
411
489
|
});
|
|
412
490
|
});
|
|
413
491
|
}
|
|
414
492
|
function normalizeOperatingHours(params) {
|
|
415
|
-
var _params$input, _params$input2, _params$input3;
|
|
493
|
+
var _params$input, _params$input2, _params$input3, _params$input4;
|
|
416
494
|
var fallbackWindows = enumerateDates(params.dateRange.startDate, params.dateRange.endDate).map(function (date) {
|
|
417
495
|
var start = toDateTimeInDate(date, params.businessHours.startTime, params.timezoneName);
|
|
418
496
|
var end = toDateTimeInDate(date, params.businessHours.endTime, params.timezoneName);
|
|
@@ -430,26 +508,32 @@ function normalizeOperatingHours(params) {
|
|
|
430
508
|
endAt: formatDateTime(range.end, params.timezoneName, params.fixedOffsetMinutes)
|
|
431
509
|
};
|
|
432
510
|
});
|
|
433
|
-
var
|
|
434
|
-
return
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
source: ((_params$input = params.input) === null || _params$input === void 0 ? void 0 : _params$input.source) || params.fallbackSource,
|
|
449
|
-
scheduleIds: uniqById(((_params$input2 = params.input) === null || _params$input2 === void 0 ? void 0 : _params$input2.scheduleIds) || []),
|
|
450
|
-
missingScheduleIds: uniqById(((_params$input3 = params.input) === null || _params$input3 === void 0 ? void 0 : _params$input3.missingScheduleIds) || []),
|
|
451
|
-
windows: windows
|
|
511
|
+
var normalizeWindows = function normalizeWindows(source) {
|
|
512
|
+
return mergeRanges(source.map(function (window) {
|
|
513
|
+
return normalizeAbsoluteRange(window, params.timezoneName);
|
|
514
|
+
}).filter(function (window) {
|
|
515
|
+
return Boolean(window);
|
|
516
|
+
}).map(function (window) {
|
|
517
|
+
return clipRange(window, params.coverage);
|
|
518
|
+
}).filter(function (window) {
|
|
519
|
+
return Boolean(window);
|
|
520
|
+
})).map(function (range) {
|
|
521
|
+
return {
|
|
522
|
+
startAt: formatDateTime(range.start, params.timezoneName, params.fixedOffsetMinutes),
|
|
523
|
+
endAt: formatDateTime(range.end, params.timezoneName, params.fixedOffsetMinutes)
|
|
524
|
+
};
|
|
525
|
+
});
|
|
452
526
|
};
|
|
527
|
+
var windows = normalizeWindows(sourceWindows);
|
|
528
|
+
var excludedWindows = normalizeWindows(((_params$input = params.input) === null || _params$input === void 0 ? void 0 : _params$input.excludedWindows) || []);
|
|
529
|
+
return _objectSpread({
|
|
530
|
+
source: ((_params$input2 = params.input) === null || _params$input2 === void 0 ? void 0 : _params$input2.source) || params.fallbackSource,
|
|
531
|
+
scheduleIds: uniqById(((_params$input3 = params.input) === null || _params$input3 === void 0 ? void 0 : _params$input3.scheduleIds) || []),
|
|
532
|
+
missingScheduleIds: uniqById(((_params$input4 = params.input) === null || _params$input4 === void 0 ? void 0 : _params$input4.missingScheduleIds) || []),
|
|
533
|
+
windows: windows
|
|
534
|
+
}, excludedWindows.length > 0 ? {
|
|
535
|
+
excludedWindows: excludedWindows
|
|
536
|
+
} : {});
|
|
453
537
|
}
|
|
454
538
|
function matchesRequirementGroup(requirementGroup, resource, product) {
|
|
455
539
|
var _requirementGroup$res;
|
|
@@ -759,11 +843,12 @@ function resolveProjectionDateRange(projection, requestDateRange) {
|
|
|
759
843
|
};
|
|
760
844
|
}
|
|
761
845
|
function buildOperatingRanges(projection, dateRange) {
|
|
846
|
+
var includeExcludedWindows = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
762
847
|
var coverage = {
|
|
763
848
|
start: toDateStart(dateRange.startDate, projection.meta.timezone),
|
|
764
849
|
end: toDateEnd(nextDate(dateRange.endDate), projection.meta.timezone)
|
|
765
850
|
};
|
|
766
|
-
return mergeRanges(projection.meta.defaults.operatingHours.windows.map(function (window) {
|
|
851
|
+
return mergeRanges([].concat(_toConsumableArray(projection.meta.defaults.operatingHours.windows), _toConsumableArray(includeExcludedWindows ? projection.meta.defaults.operatingHours.excludedWindows || [] : [])).map(function (window) {
|
|
767
852
|
return normalizeAbsoluteRange(window, projection.meta.timezone);
|
|
768
853
|
}).filter(function (window) {
|
|
769
854
|
return Boolean(window);
|
|
@@ -774,12 +859,13 @@ function buildOperatingRanges(projection, dateRange) {
|
|
|
774
859
|
}));
|
|
775
860
|
}
|
|
776
861
|
function buildResourceWindowIndex(projection) {
|
|
862
|
+
var includeExcludedWindows = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
777
863
|
var coverage = {
|
|
778
864
|
start: toDateTime(projection.meta.coverage.startAt, projection.meta.timezone),
|
|
779
865
|
end: toDateTime(projection.meta.coverage.endAt, projection.meta.timezone)
|
|
780
866
|
};
|
|
781
867
|
return new Map(projection.resources.map(function (resource) {
|
|
782
|
-
return [String(resource.id), normalizeResourceWindow(resource, coverage, projection.meta.timezone)];
|
|
868
|
+
return [String(resource.id), normalizeResourceWindow(resource, coverage, projection.meta.timezone, includeExcludedWindows)];
|
|
783
869
|
}));
|
|
784
870
|
}
|
|
785
871
|
function buildGroupWorkingRanges(params) {
|
|
@@ -801,7 +887,7 @@ function buildGroupWorkingRanges(params) {
|
|
|
801
887
|
return !filteredResourceIdSet || filteredResourceIdSet.has(String(resource.id));
|
|
802
888
|
}).map(function (resource) {
|
|
803
889
|
var _params$resourceWindo;
|
|
804
|
-
var windows = ((_params$resourceWindo = params.resourceWindowIndex) === null || _params$resourceWindo === void 0 ? void 0 : _params$resourceWindo.get(String(resource.id))) || normalizeResourceWindow(resource, coverage, projection.meta.timezone);
|
|
890
|
+
var windows = ((_params$resourceWindo = params.resourceWindowIndex) === null || _params$resourceWindo === void 0 ? void 0 : _params$resourceWindo.get(String(resource.id))) || normalizeResourceWindow(resource, coverage, projection.meta.timezone, params.includeExcludedWindows === true);
|
|
805
891
|
return windows.map(function (window) {
|
|
806
892
|
return clipRange(window, coverage);
|
|
807
893
|
}).filter(function (window) {
|
|
@@ -848,11 +934,12 @@ function buildGroupWorkingRanges(params) {
|
|
|
848
934
|
return mergeRanges(satisfiedRanges);
|
|
849
935
|
}
|
|
850
936
|
function materializeScheduleRules(rules, dateRange, timezoneName, fixedOffsetMinutes) {
|
|
937
|
+
var allowExcludedScheduleDates = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
851
938
|
var dates = enumerateDates(dateRange.startDate, dateRange.endDate);
|
|
852
939
|
var seen = new Map();
|
|
853
940
|
rules.forEach(function (rule) {
|
|
854
941
|
dates.forEach(function (date) {
|
|
855
|
-
if (!matchesScheduleRuleDate(rule, date, timezoneName)) return;
|
|
942
|
+
if (!matchesScheduleRuleDate(rule, date, timezoneName, allowExcludedScheduleDates)) return;
|
|
856
943
|
var start = toDateTimeInDate(date, rule.startTime, timezoneName);
|
|
857
944
|
var end = toDateTimeInDate(date, rule.endTime, timezoneName);
|
|
858
945
|
if (end <= start) end = toDateTimeInDate(nextDate(date, timezoneName), rule.endTime, timezoneName);
|
|
@@ -885,8 +972,9 @@ function materializeScheduleRules(rules, dateRange, timezoneName, fixedOffsetMin
|
|
|
885
972
|
}
|
|
886
973
|
function matchesScheduleRuleDate(rule, date, _timezoneName) {
|
|
887
974
|
var _rule$includeDates, _rule$excludeDates;
|
|
975
|
+
var allowExcludedScheduleDate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
888
976
|
if ((_rule$includeDates = rule.includeDates) !== null && _rule$includeDates !== void 0 && _rule$includeDates.includes(date)) return true;
|
|
889
|
-
if ((_rule$excludeDates = rule.excludeDates) !== null && _rule$excludeDates !== void 0 && _rule$excludeDates.includes(date)) return false;
|
|
977
|
+
if (!allowExcludedScheduleDate && (_rule$excludeDates = rule.excludeDates) !== null && _rule$excludeDates !== void 0 && _rule$excludeDates.includes(date)) return false;
|
|
890
978
|
if (rule.startDate && date < rule.startDate) return false;
|
|
891
979
|
if (rule.endDate && date > rule.endDate) return false;
|
|
892
980
|
if (rule.mode === 'designation') {
|
|
@@ -942,6 +1030,7 @@ function buildGroupResourceIndex(params) {
|
|
|
942
1030
|
}
|
|
943
1031
|
function getSessionRangesForProduct(projection, product, dateRange) {
|
|
944
1032
|
var _extractFixedOffsetMi2;
|
|
1033
|
+
var allowExcludedScheduleDates = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
945
1034
|
var fixedOffsetMinutes = (_extractFixedOffsetMi2 = extractFixedOffsetMinutes(projection.meta.now)) !== null && _extractFixedOffsetMi2 !== void 0 ? _extractFixedOffsetMi2 : captureRuntimeOffsetMinutes();
|
|
946
1035
|
var ranges = (product.sessionRanges || []).map(function (range) {
|
|
947
1036
|
var _range$scheduleRefs2;
|
|
@@ -967,7 +1056,7 @@ function getSessionRangesForProduct(projection, product, dateRange) {
|
|
|
967
1056
|
primaryScheduleRef: (_range$scheduleRefs2 = range.scheduleRefs) === null || _range$scheduleRefs2 === void 0 ? void 0 : _range$scheduleRefs2[0]
|
|
968
1057
|
};
|
|
969
1058
|
}).filter(Boolean);
|
|
970
|
-
var ruleRanges = materializeScheduleRules(product.sessionRules || [], dateRange, projection.meta.timezone, fixedOffsetMinutes);
|
|
1059
|
+
var ruleRanges = materializeScheduleRules(product.sessionRules || [], dateRange, projection.meta.timezone, fixedOffsetMinutes, allowExcludedScheduleDates);
|
|
971
1060
|
return dedupeProductRanges([].concat(_toConsumableArray(ranges), _toConsumableArray(ruleRanges.map(function (range) {
|
|
972
1061
|
return _objectSpread(_objectSpread({}, range), {}, {
|
|
973
1062
|
key: "".concat(String(product.id), ":").concat(range.startAt, ":").concat(range.endAt),
|
|
@@ -1022,7 +1111,8 @@ export function getProductTimeRanges(projection) {
|
|
|
1022
1111
|
var dateRange = resolveProjectionDateRange(projection, request.dateRange);
|
|
1023
1112
|
var slotStepMinutes = projection.meta.defaults.slotStepMinutes;
|
|
1024
1113
|
var fixedOffsetMinutes = (_extractFixedOffsetMi3 = extractFixedOffsetMinutes(projection.meta.now)) !== null && _extractFixedOffsetMi3 !== void 0 ? _extractFixedOffsetMi3 : captureRuntimeOffsetMinutes();
|
|
1025
|
-
var
|
|
1114
|
+
var allowExcludedScheduleDateOverride = runtimeOptions.allowExcludedScheduleDateOverride === true;
|
|
1115
|
+
var resourceWindowIndex = buildResourceWindowIndex(projection, allowExcludedScheduleDateOverride);
|
|
1026
1116
|
var filteredProductIdSet = (_request$productIds = request.productIds) !== null && _request$productIds !== void 0 && _request$productIds.length ? new Set(request.productIds.map(String)) : null;
|
|
1027
1117
|
return projection.products.filter(function (product) {
|
|
1028
1118
|
return !filteredProductIdSet || filteredProductIdSet.has(String(product.id));
|
|
@@ -1037,7 +1127,7 @@ export function getProductTimeRanges(projection) {
|
|
|
1037
1127
|
};
|
|
1038
1128
|
}
|
|
1039
1129
|
if (product.kind === 'session' || product.kind === 'venue_slot') {
|
|
1040
|
-
var fixedRanges = getSessionRangesForProduct(projection, product, dateRange);
|
|
1130
|
+
var fixedRanges = getSessionRangesForProduct(projection, product, dateRange, allowExcludedScheduleDateOverride);
|
|
1041
1131
|
var customRanges = [];
|
|
1042
1132
|
var customDurationMinutes = resolveRequestedSessionDurationMinutes(product, request, runtimeOptions.allowSessionCustomRanges === true);
|
|
1043
1133
|
var _requestedStartTimes = resolveRequestedDurationStartTimes(product, request, runtimeOptions.allowSessionCustomRanges === true);
|
|
@@ -1059,7 +1149,10 @@ export function getProductTimeRanges(projection) {
|
|
|
1059
1149
|
var requiredGroups = (product.requirementGroups || []).filter(function (group) {
|
|
1060
1150
|
return group.required !== false;
|
|
1061
1151
|
});
|
|
1062
|
-
var operatingRanges = buildOperatingRanges(projection, dateRange);
|
|
1152
|
+
var operatingRanges = buildOperatingRanges(projection, dateRange, allowExcludedScheduleDateOverride);
|
|
1153
|
+
var operatingEndAt = dateRange.startDate === dateRange.endDate && operatingRanges.length > 0 ? formatDateTime(Math.max.apply(Math, _toConsumableArray(operatingRanges.map(function (range) {
|
|
1154
|
+
return range.end;
|
|
1155
|
+
}))), projection.meta.timezone, fixedOffsetMinutes) : undefined;
|
|
1063
1156
|
var resourceRanges = requiredGroups.length ? requiredGroups.map(function (group) {
|
|
1064
1157
|
return buildGroupWorkingRanges({
|
|
1065
1158
|
projection: projection,
|
|
@@ -1068,7 +1161,8 @@ export function getProductTimeRanges(projection) {
|
|
|
1068
1161
|
dateRange: dateRange,
|
|
1069
1162
|
resourceIds: request.resourceIds,
|
|
1070
1163
|
partySize: normalizedPartySize,
|
|
1071
|
-
resourceWindowIndex: resourceWindowIndex
|
|
1164
|
+
resourceWindowIndex: resourceWindowIndex,
|
|
1165
|
+
includeExcludedWindows: allowExcludedScheduleDateOverride
|
|
1072
1166
|
});
|
|
1073
1167
|
}).reduce(function (current, ranges) {
|
|
1074
1168
|
return current === null ? ranges : intersectRangeLists(current, ranges);
|
|
@@ -1127,13 +1221,16 @@ export function getProductTimeRanges(projection) {
|
|
|
1127
1221
|
ranges.push(createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes));
|
|
1128
1222
|
});
|
|
1129
1223
|
}
|
|
1130
|
-
return {
|
|
1224
|
+
return _objectSpread(_objectSpread({
|
|
1131
1225
|
productId: product.id,
|
|
1132
1226
|
title: product.title,
|
|
1133
1227
|
kind: product.kind,
|
|
1134
|
-
slotStepMinutes: slotStepMinutes
|
|
1228
|
+
slotStepMinutes: slotStepMinutes
|
|
1229
|
+
}, operatingEndAt ? {
|
|
1230
|
+
operatingEndAt: operatingEndAt
|
|
1231
|
+
} : {}), {}, {
|
|
1135
1232
|
ranges: dedupeProductRanges(ranges)
|
|
1136
|
-
};
|
|
1233
|
+
});
|
|
1137
1234
|
});
|
|
1138
1235
|
}
|
|
1139
1236
|
function aggregateMatchedCells(productId, requirementGroupId, resourceId, candidateRange, indexedCells) {
|
|
@@ -1347,7 +1444,8 @@ function buildEvaluationContext(params) {
|
|
|
1347
1444
|
evaluatedAt: evaluatedAt,
|
|
1348
1445
|
evaluatedAtMs: evaluatedAt,
|
|
1349
1446
|
resourceIdSet: (_params$resourceIds2 = params.resourceIds) !== null && _params$resourceIds2 !== void 0 && _params$resourceIds2.length ? new Set(params.resourceIds.map(String)) : null,
|
|
1350
|
-
selectionsByGroupKey: selectionsByGroupKey
|
|
1447
|
+
selectionsByGroupKey: selectionsByGroupKey,
|
|
1448
|
+
allowExcludedScheduleDateOverride: params.allowExcludedScheduleDateOverride === true
|
|
1351
1449
|
};
|
|
1352
1450
|
}
|
|
1353
1451
|
function summarizeStatuses(statuses) {
|
|
@@ -1519,7 +1617,8 @@ function evaluateCandidateSummary(projection, candidate, request) {
|
|
|
1519
1617
|
var evaluationContext = request.evaluationContext || buildEvaluationContext({
|
|
1520
1618
|
projection: projection,
|
|
1521
1619
|
evaluatedAt: request.evaluatedAt,
|
|
1522
|
-
resourceIds: request.resourceIds
|
|
1620
|
+
resourceIds: request.resourceIds,
|
|
1621
|
+
allowExcludedScheduleDateOverride: request.allowExcludedScheduleDateOverride
|
|
1523
1622
|
});
|
|
1524
1623
|
var requestedPartySize = normalizePartySize(request.partySize);
|
|
1525
1624
|
var requiredGroups = (product.requirementGroups || []).filter(function (group) {
|
|
@@ -1537,7 +1636,9 @@ function evaluateCandidateSummary(projection, candidate, request) {
|
|
|
1537
1636
|
});
|
|
1538
1637
|
});
|
|
1539
1638
|
var gate = evaluateCandidateTimeGate({
|
|
1639
|
+
projection: projection,
|
|
1540
1640
|
product: product,
|
|
1641
|
+
candidate: candidate,
|
|
1541
1642
|
candidateRange: candidateRange,
|
|
1542
1643
|
evaluationContext: evaluationContext,
|
|
1543
1644
|
timezoneName: projection.meta.timezone
|
|
@@ -1592,7 +1693,8 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1592
1693
|
projection: projection,
|
|
1593
1694
|
evaluatedAt: request.evaluatedAt,
|
|
1594
1695
|
resourceIds: request.resourceIds,
|
|
1595
|
-
requirementSelections: request.requirementSelections
|
|
1696
|
+
requirementSelections: request.requirementSelections,
|
|
1697
|
+
allowExcludedScheduleDateOverride: request.allowExcludedScheduleDateOverride
|
|
1596
1698
|
});
|
|
1597
1699
|
var requestedPartySize = normalizePartySize(request.partySize);
|
|
1598
1700
|
var partySize = requestedPartySize !== null && requestedPartySize !== void 0 ? requestedPartySize : 1;
|
|
@@ -1615,6 +1717,12 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1615
1717
|
var options = matchedResources.map(function (resource) {
|
|
1616
1718
|
var _request$cellIndex, _resource$raw2;
|
|
1617
1719
|
var matchedCell = aggregateMatchedCells(product.id, requirementGroup.id, resource.id, candidateRange, ((_request$cellIndex = request.cellIndex) === null || _request$cellIndex === void 0 ? void 0 : _request$cellIndex.get([String(product.id), requirementGroup.id, String(resource.id)].join(':'))) || []);
|
|
1720
|
+
var isExcludedScheduleDate = evaluationContext.allowExcludedScheduleDateOverride && isRangeFromExcludedWindows({
|
|
1721
|
+
normalWindows: resource.windows || [],
|
|
1722
|
+
excludedWindows: resource.excludedWindows || [],
|
|
1723
|
+
candidateRange: candidateRange,
|
|
1724
|
+
timezoneName: projection.meta.timezone
|
|
1725
|
+
});
|
|
1618
1726
|
if (!matchedCell) {
|
|
1619
1727
|
var _resource$raw;
|
|
1620
1728
|
var _isPast = candidateRange.endMs <= evaluationContext.evaluatedAtMs;
|
|
@@ -1626,7 +1734,7 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1626
1734
|
resourceType: resource.resourceType,
|
|
1627
1735
|
status: _isPast ? 'past' : 'unavailable',
|
|
1628
1736
|
maxPartySize: 0,
|
|
1629
|
-
reasonCodes: _isPast ? ['past'] : ['outside_resource_window']
|
|
1737
|
+
reasonCodes: _isPast ? ['past'] : [].concat(_toConsumableArray(isExcludedScheduleDate ? ['schedule_excluded_date'] : []), ['outside_resource_window'])
|
|
1630
1738
|
};
|
|
1631
1739
|
}
|
|
1632
1740
|
var remainingCapacity = matchedCell.remainingCapacity;
|
|
@@ -1634,6 +1742,7 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1634
1742
|
var isPast = candidateRange.endMs <= evaluationContext.evaluatedAtMs;
|
|
1635
1743
|
var maxPartySize = isPast ? 0 : Math.max(0, remainingCapacity || 0);
|
|
1636
1744
|
var requiredCapacity = resolveRequiredCapacity(requirementGroup, product, requestedPartySize);
|
|
1745
|
+
var reasonCodes = Array.from(new Set([].concat(_toConsumableArray(matchedCell.reasonCodes), _toConsumableArray(isExcludedScheduleDate ? ['schedule_excluded_date'] : []))));
|
|
1637
1746
|
var status = function () {
|
|
1638
1747
|
if (isPast) return 'past';
|
|
1639
1748
|
if (matchedCell.status === 'unavailable') return 'unavailable';
|
|
@@ -1651,7 +1760,7 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1651
1760
|
remainingCapacity: remainingCapacity,
|
|
1652
1761
|
maxCapacity: maxCapacity,
|
|
1653
1762
|
maxPartySize: maxPartySize,
|
|
1654
|
-
reasonCodes: isPast ? Array.from(new Set([].concat(
|
|
1763
|
+
reasonCodes: isPast ? Array.from(new Set([].concat(reasonCodes, ['past']))) : reasonCodes,
|
|
1655
1764
|
matchedCell: matchedCell
|
|
1656
1765
|
};
|
|
1657
1766
|
});
|
|
@@ -1709,7 +1818,9 @@ function evaluateCandidate(projection, candidate, request) {
|
|
|
1709
1818
|
return group.status;
|
|
1710
1819
|
});
|
|
1711
1820
|
var gate = evaluateCandidateTimeGate({
|
|
1821
|
+
projection: projection,
|
|
1712
1822
|
product: product,
|
|
1823
|
+
candidate: candidate,
|
|
1713
1824
|
candidateRange: candidateRange,
|
|
1714
1825
|
evaluationContext: evaluationContext,
|
|
1715
1826
|
timezoneName: projection.meta.timezone
|
|
@@ -1798,6 +1909,7 @@ function assertRangesWithinProjection(projection, ranges) {
|
|
|
1798
1909
|
}
|
|
1799
1910
|
export function queryAvailabilityProjection(projection, request) {
|
|
1800
1911
|
var _extractFixedOffsetMi6, _request$productIds2;
|
|
1912
|
+
var runtimeOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1801
1913
|
var normalizedPartySize = normalizePartySize(request.partySize);
|
|
1802
1914
|
var evaluatedAt = formatDateTime(localDateToScalar(new Date()), projection.meta.timezone, (_extractFixedOffsetMi6 = extractFixedOffsetMinutes(projection.meta.now)) !== null && _extractFixedOffsetMi6 !== void 0 ? _extractFixedOffsetMi6 : captureRuntimeOffsetMinutes());
|
|
1803
1915
|
if (request.target === 'time') {
|
|
@@ -1820,7 +1932,8 @@ export function queryAvailabilityProjection(projection, request) {
|
|
|
1820
1932
|
var evaluationContext = buildEvaluationContext({
|
|
1821
1933
|
projection: projection,
|
|
1822
1934
|
evaluatedAt: evaluatedAt,
|
|
1823
|
-
resourceIds: request.resourceIds
|
|
1935
|
+
resourceIds: request.resourceIds,
|
|
1936
|
+
allowExcludedScheduleDateOverride: runtimeOptions.allowExcludedScheduleDateOverride
|
|
1824
1937
|
});
|
|
1825
1938
|
if (request.target === 'time') {
|
|
1826
1939
|
var candidates = dedupeProductRanges(request.candidates);
|
|
@@ -1908,7 +2021,8 @@ export function queryAvailabilityProjection(projection, request) {
|
|
|
1908
2021
|
resourceIds: request.resourceIds,
|
|
1909
2022
|
partySize: normalizedPartySize
|
|
1910
2023
|
}, {
|
|
1911
|
-
evaluatedAt: evaluatedAt
|
|
2024
|
+
evaluatedAt: evaluatedAt,
|
|
2025
|
+
allowExcludedScheduleDateOverride: runtimeOptions.allowExcludedScheduleDateOverride
|
|
1912
2026
|
});
|
|
1913
2027
|
var candidateGroupMap = new Map(candidateGroups.map(function (group) {
|
|
1914
2028
|
return [String(group.productId), group];
|
|
@@ -2086,6 +2200,7 @@ function summarizeProductStatus(statuses) {
|
|
|
2086
2200
|
}
|
|
2087
2201
|
export function validateAvailabilitySelection(projection, params) {
|
|
2088
2202
|
var _extractFixedOffsetMi7;
|
|
2203
|
+
var runtimeOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
2089
2204
|
var normalizedPartySize = normalizePartySize(params.partySize);
|
|
2090
2205
|
var normalizedBookingCount = normalizeBookingCount(params.bookingCount);
|
|
2091
2206
|
assertRangesWithinProjection(projection, [params.candidate]);
|
|
@@ -2106,14 +2221,15 @@ export function validateAvailabilitySelection(projection, params) {
|
|
|
2106
2221
|
evaluationContext: buildEvaluationContext({
|
|
2107
2222
|
projection: projection,
|
|
2108
2223
|
evaluatedAt: evaluatedAt,
|
|
2109
|
-
requirementSelections: params.requirementSelections
|
|
2224
|
+
requirementSelections: params.requirementSelections,
|
|
2225
|
+
allowExcludedScheduleDateOverride: runtimeOptions.allowExcludedScheduleDateOverride
|
|
2110
2226
|
})
|
|
2111
2227
|
});
|
|
2112
2228
|
var conflicts = [];
|
|
2113
2229
|
if (evaluated.gate) {
|
|
2114
2230
|
conflicts.push({
|
|
2115
2231
|
code: evaluated.gate.conflictCode,
|
|
2116
|
-
message: evaluated.gate.
|
|
2232
|
+
message: evaluated.gate.conflictCode === 'past' ? '候选时间已过期' : evaluated.gate.conflictCode === 'schedule_excluded_date' ? '候选日期已被日程排除' : '候选时间不满足预订时间门禁',
|
|
2117
2233
|
reasonCodes: evaluated.gate.reasonCodes,
|
|
2118
2234
|
productId: params.candidate.productId,
|
|
2119
2235
|
candidateKey: params.candidate.key
|
|
@@ -101,6 +101,9 @@ export interface AvailabilityOperatingHoursSnapshot {
|
|
|
101
101
|
scheduleIds: AvailabilityId[];
|
|
102
102
|
missingScheduleIds: AvailabilityId[];
|
|
103
103
|
windows: AvailabilityResourceWindow[];
|
|
104
|
+
/** Schedule windows omitted only because their date is excluded. POS may use
|
|
105
|
+
* these to surface an unavailable, manually selectable candidate. */
|
|
106
|
+
excludedWindows?: AvailabilityResourceWindow[];
|
|
104
107
|
}
|
|
105
108
|
export interface AvailabilityResource {
|
|
106
109
|
id: AvailabilityId;
|
|
@@ -110,6 +113,8 @@ export interface AvailabilityResource {
|
|
|
110
113
|
resourceType: AvailabilityResourceType;
|
|
111
114
|
capacity: number;
|
|
112
115
|
windows: AvailabilityResourceWindow[];
|
|
116
|
+
/** Resource work windows omitted only by an excluded schedule date. */
|
|
117
|
+
excludedWindows?: AvailabilityResourceWindow[];
|
|
113
118
|
raw?: Record<string, any>;
|
|
114
119
|
}
|
|
115
120
|
export interface AvailabilityOccupancy extends AvailabilityAbsoluteRange {
|
|
@@ -213,6 +218,8 @@ export interface ProductTimeRangeGroup {
|
|
|
213
218
|
title?: string;
|
|
214
219
|
kind: AvailabilityProductKind;
|
|
215
220
|
slotStepMinutes?: number;
|
|
221
|
+
/** 单日查询对应营业窗口的最终结束时刻,不受资源排班是否为空影响。 */
|
|
222
|
+
operatingEndAt?: string;
|
|
216
223
|
ranges: ProductTimeRange[];
|
|
217
224
|
}
|
|
218
225
|
export interface AvailabilityAssignment extends AvailabilityAbsoluteRange {
|
|
@@ -250,6 +257,11 @@ export interface GetProductTimeRangesRuntimeOptions {
|
|
|
250
257
|
* disabled.
|
|
251
258
|
*/
|
|
252
259
|
allowSessionCustomRanges?: boolean;
|
|
260
|
+
/**
|
|
261
|
+
* Internal POS capability: materialize candidates whose schedule date was
|
|
262
|
+
* explicitly excluded, while availability evaluation keeps them unavailable.
|
|
263
|
+
*/
|
|
264
|
+
allowExcludedScheduleDateOverride?: boolean;
|
|
253
265
|
}
|
|
254
266
|
export interface QueryAvailabilityBaseRequest {
|
|
255
267
|
productIds?: AvailabilityId[];
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 2 |
|
|
329
|
+
weekNum: 0 | 2 | 3 | 1 | 5 | 6 | 4;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|