@pisell/pisellos 2.3.99 → 2.3.100
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 +30 -2
- package/dist/modules/ResourcePlanner/types.d.ts +4 -0
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/UnifiedBookingSales/index.d.ts +1 -1
- package/dist/solution/UnifiedBookingSales/index.js +8 -3
- package/lib/modules/ResourcePlanner/planner.d.ts +2 -2
- package/lib/modules/ResourcePlanner/planner.js +28 -1
- package/lib/modules/ResourcePlanner/types.d.ts +4 -0
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/UnifiedBookingSales/index.d.ts +1 -1
- package/lib/solution/UnifiedBookingSales/index.js +7 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AvailabilityProjection, AvailabilityProjectionInput, AvailabilityQuery, AvailabilityQueryResult, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, GetProductTimeRangesRequest, ProductTimeRangeGroup } from './types';
|
|
1
|
+
import type { AvailabilityProjection, AvailabilityProjectionInput, AvailabilityQuery, AvailabilityQueryResult, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, GetProductTimeRangesRequest, GetProductTimeRangesRuntimeOptions, ProductTimeRangeGroup } from './types';
|
|
2
2
|
export declare function createAvailabilityProjection(input: AvailabilityProjectionInput): AvailabilityProjection;
|
|
3
|
-
export declare function getProductTimeRanges(projection: AvailabilityProjection, request?: GetProductTimeRangesRequest): ProductTimeRangeGroup[];
|
|
3
|
+
export declare function getProductTimeRanges(projection: AvailabilityProjection, request?: GetProductTimeRangesRequest, runtimeOptions?: GetProductTimeRangesRuntimeOptions): ProductTimeRangeGroup[];
|
|
4
4
|
export declare function queryAvailabilityProjection(projection: AvailabilityProjection, request: AvailabilityQuery): AvailabilityQueryResult;
|
|
5
5
|
export declare function validateAvailabilitySelection(projection: AvailabilityProjection, params: AvailabilitySelectionValidationParams): AvailabilitySelectionValidationResult;
|
|
@@ -96,6 +96,9 @@ function addMinutesZoned(value, minutes, _timezoneName) {
|
|
|
96
96
|
function ceilToTenMinutes(value, _timezoneName) {
|
|
97
97
|
return ceilLocalScalarToTenMinutes(value);
|
|
98
98
|
}
|
|
99
|
+
function floorToMinute(value) {
|
|
100
|
+
return Math.floor(value / 60000) * 60000;
|
|
101
|
+
}
|
|
99
102
|
function nextDate(value, _timezoneName) {
|
|
100
103
|
return getNextLocalDate(value);
|
|
101
104
|
}
|
|
@@ -981,6 +984,9 @@ function dedupeProductRanges(ranges) {
|
|
|
981
984
|
}
|
|
982
985
|
function createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes) {
|
|
983
986
|
var bookingEnd = addMinutesZoned(start, durationMinutes, projection.meta.timezone);
|
|
987
|
+
return createDurationTimeRangeWithEnd(product, start, bookingEnd, projection, fixedOffsetMinutes);
|
|
988
|
+
}
|
|
989
|
+
function createDurationTimeRangeWithEnd(product, start, bookingEnd, projection, fixedOffsetMinutes) {
|
|
984
990
|
return {
|
|
985
991
|
key: "".concat(String(product.id), ":").concat(start, ":").concat(bookingEnd),
|
|
986
992
|
productId: product.id,
|
|
@@ -999,6 +1005,7 @@ function createDurationTimeRange(product, start, durationMinutes, projection, fi
|
|
|
999
1005
|
export function getProductTimeRanges(projection) {
|
|
1000
1006
|
var _extractFixedOffsetMi3, _request$productIds;
|
|
1001
1007
|
var request = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1008
|
+
var runtimeOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1002
1009
|
var normalizedPartySize = normalizePartySize(request.partySize);
|
|
1003
1010
|
var dateRange = resolveProjectionDateRange(projection, request.dateRange);
|
|
1004
1011
|
var slotStepMinutes = projection.meta.defaults.slotStepMinutes;
|
|
@@ -1045,10 +1052,29 @@ export function getProductTimeRanges(projection) {
|
|
|
1045
1052
|
}, null) || [] : null;
|
|
1046
1053
|
var baseRanges = resourceRanges === null ? operatingRanges : intersectRangeLists(resourceRanges, operatingRanges);
|
|
1047
1054
|
var durationMinutes = resolveRequestedDurationMinutes(product, request);
|
|
1055
|
+
var flexibleStartAt = function () {
|
|
1056
|
+
if (!product.isFlexibleDuration) return undefined;
|
|
1057
|
+
var evaluatedAt = toDateTime(runtimeOptions.evaluatedAt || projection.meta.durationCandidateAnchorAt, projection.meta.timezone);
|
|
1058
|
+
if (!Number.isFinite(evaluatedAt)) {
|
|
1059
|
+
throw availabilityError('INVALID_TARGET_FILTER', 'runtimeOptions.evaluatedAt 必须是有效时间', {
|
|
1060
|
+
evaluatedAt: runtimeOptions.evaluatedAt
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
return floorToMinute(evaluatedAt);
|
|
1064
|
+
}();
|
|
1048
1065
|
var durationAnchor = ceilToTenMinutes(toDateTime(projection.meta.durationCandidateAnchorAt, projection.meta.timezone), projection.meta.timezone);
|
|
1049
1066
|
var requestedStartTimes = resolveRequestedDurationStartTimes(product, request);
|
|
1050
1067
|
var ranges = [];
|
|
1051
1068
|
baseRanges.forEach(function (range) {
|
|
1069
|
+
if (product.isFlexibleDuration && flexibleStartAt !== undefined) {
|
|
1070
|
+
var start = Math.max(range.start, flexibleStartAt);
|
|
1071
|
+
if (start >= range.end) return;
|
|
1072
|
+
var bookingDate = formatDate(start);
|
|
1073
|
+
if (bookingDate >= dateRange.startDate && bookingDate <= dateRange.endDate) {
|
|
1074
|
+
ranges.push(createDurationTimeRangeWithEnd(product, start, range.end, projection, fixedOffsetMinutes));
|
|
1075
|
+
}
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1052
1078
|
if (range.end <= durationAnchor) return;
|
|
1053
1079
|
var cursor = range.start;
|
|
1054
1080
|
if (cursor < durationAnchor) {
|
|
@@ -1057,8 +1083,8 @@ export function getProductTimeRanges(projection) {
|
|
|
1057
1083
|
while (true) {
|
|
1058
1084
|
var bookingEnd = addMinutesZoned(cursor, durationMinutes, projection.meta.timezone);
|
|
1059
1085
|
if (bookingEnd > range.end) break;
|
|
1060
|
-
var
|
|
1061
|
-
if (
|
|
1086
|
+
var _bookingDate = formatDate(cursor);
|
|
1087
|
+
if (_bookingDate >= dateRange.startDate && _bookingDate <= dateRange.endDate) {
|
|
1062
1088
|
ranges.push(createDurationTimeRange(product, cursor, durationMinutes, projection, fixedOffsetMinutes));
|
|
1063
1089
|
}
|
|
1064
1090
|
cursor = addMinutesZoned(cursor, slotStepMinutes, projection.meta.timezone);
|
|
@@ -1858,6 +1884,8 @@ export function queryAvailabilityProjection(projection, request) {
|
|
|
1858
1884
|
dateRange: dateRange,
|
|
1859
1885
|
resourceIds: request.resourceIds,
|
|
1860
1886
|
partySize: normalizedPartySize
|
|
1887
|
+
}, {
|
|
1888
|
+
evaluatedAt: evaluatedAt
|
|
1861
1889
|
});
|
|
1862
1890
|
var candidateGroupMap = new Map(candidateGroups.map(function (group) {
|
|
1863
1891
|
return [String(group.productId), group];
|
|
@@ -81,6 +81,7 @@ export interface AvailabilityProduct {
|
|
|
81
81
|
id: AvailabilityId;
|
|
82
82
|
title?: string;
|
|
83
83
|
kind: AvailabilityProductKind;
|
|
84
|
+
isFlexibleDuration?: boolean;
|
|
84
85
|
durationMinutes?: number;
|
|
85
86
|
quantity?: number;
|
|
86
87
|
capacityRequired?: number;
|
|
@@ -240,6 +241,9 @@ export interface GetProductTimeRangesRequest {
|
|
|
240
241
|
*/
|
|
241
242
|
allowOutsideOperatingHoursForRequestedStartTimes?: boolean;
|
|
242
243
|
}
|
|
244
|
+
export interface GetProductTimeRangesRuntimeOptions {
|
|
245
|
+
evaluatedAt?: string;
|
|
246
|
+
}
|
|
243
247
|
export interface QueryAvailabilityBaseRequest {
|
|
244
248
|
productIds?: AvailabilityId[];
|
|
245
249
|
resourceIds?: 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 |
|
|
329
|
+
weekNum: 0 | 5 | 3 | 1 | 2 | 4 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "sold_out" | "lots_of_space" | "filling_up_fast";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -244,7 +244,7 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
244
244
|
private releaseAvailabilityCommitLock;
|
|
245
245
|
/** IO boundary: loads catalog, schedules, resources, occupancies, and registers one context. */
|
|
246
246
|
prepareAvailabilityProjection(params: UnifiedBookingSalesPrepareAvailabilityProjectionParams): Promise<AvailabilityContextRef>;
|
|
247
|
-
/**
|
|
247
|
+
/** Candidate calculation over the current context projection and runtime minute. */
|
|
248
248
|
getProductTimeRanges(contextId: string, request?: GetProductTimeRangesRequest): Promise<ContextualProductTimeRangeGroup[]>;
|
|
249
249
|
/** Thin facade: auto-refresh on cart drift, then delegate to the pure projection query. */
|
|
250
250
|
queryBookingAvailability(contextId: string, request: ContextualAvailabilityQuery): Promise<ContextualAvailabilityQueryResult>;
|
|
@@ -36,6 +36,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
|
|
|
36
36
|
import dayjs from 'dayjs';
|
|
37
37
|
import { cloneDeep } from 'lodash-es';
|
|
38
38
|
import { OpenDataModule } from "../../modules";
|
|
39
|
+
import { isProductFlexibleDuration } from "../../modules/BookingContext/utils";
|
|
39
40
|
import { getScheduleStartEndTimePoints } from "../../modules/Schedule/getDateIsInSchedule";
|
|
40
41
|
import { AvailabilityError, createAvailabilityProjection, getProductTimeRanges as getProjectionProductTimeRanges, queryAvailabilityProjection, validateAvailabilitySelection } from "../../modules/ResourcePlanner";
|
|
41
42
|
import { UnifiedBookingSalesHooks } from "./types";
|
|
@@ -544,6 +545,7 @@ export function normalizeProductForAvailability(product) {
|
|
|
544
545
|
var fixedOffsetMinutes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : captureRuntimeOffsetMinutes();
|
|
545
546
|
var raw = product;
|
|
546
547
|
var kind = resolveProductKind(raw);
|
|
548
|
+
var isFlexibleDuration = kind === 'duration' && isProductFlexibleDuration(raw.duration);
|
|
547
549
|
var sessionRules = [];
|
|
548
550
|
var sessionRanges = [];
|
|
549
551
|
var explicitSession = ((_raw$cartDetailValue = raw.cartDetailValue) === null || _raw$cartDetailValue === void 0 ? void 0 : _raw$cartDetailValue.session) || ((_raw$_extend = raw._extend) === null || _raw$_extend === void 0 || (_raw$_extend = _raw$_extend.other) === null || _raw$_extend === void 0 ? void 0 : _raw$_extend.session) || raw.session;
|
|
@@ -565,7 +567,8 @@ export function normalizeProductForAvailability(product) {
|
|
|
565
567
|
id: (_raw$id = raw.id) !== null && _raw$id !== void 0 ? _raw$id : raw.product_id,
|
|
566
568
|
title: pickLocalizedText(raw.title || raw.name || raw.product_title),
|
|
567
569
|
kind: kind,
|
|
568
|
-
|
|
570
|
+
isFlexibleDuration: isFlexibleDuration || undefined,
|
|
571
|
+
durationMinutes: kind === 'duration' && !isFlexibleDuration ? Math.max(1, Number(((_raw$duration = raw.duration) === null || _raw$duration === void 0 ? void 0 : _raw$duration.value) || raw.duration || raw.service_duration || 30) || 30) : undefined,
|
|
569
572
|
requirementGroups: normalizeRequirementGroups(raw),
|
|
570
573
|
sessionRules: sessionRules,
|
|
571
574
|
sessionRanges: sessionRanges,
|
|
@@ -4457,7 +4460,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4457
4460
|
return _prepareAvailabilityProjection.apply(this, arguments);
|
|
4458
4461
|
}
|
|
4459
4462
|
return prepareAvailabilityProjection;
|
|
4460
|
-
}() /**
|
|
4463
|
+
}() /** Candidate calculation over the current context projection and runtime minute. */)
|
|
4461
4464
|
}, {
|
|
4462
4465
|
key: "getProductTimeRanges",
|
|
4463
4466
|
value: (function () {
|
|
@@ -4488,7 +4491,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
4488
4491
|
});
|
|
4489
4492
|
return _context40.abrupt("return", getProjectionProductTimeRanges(projectionEntry.projection, _objectSpread(_objectSpread({}, request), allowOutsideOperatingHoursForRequestedStartTimes ? {
|
|
4490
4493
|
allowOutsideOperatingHoursForRequestedStartTimes: true
|
|
4491
|
-
} : {})
|
|
4494
|
+
} : {}), {
|
|
4495
|
+
evaluatedAt: this.getAvailabilityRuntimeDateTime()
|
|
4496
|
+
}).map(function (group) {
|
|
4492
4497
|
return _objectSpread(_objectSpread({}, group), {}, {
|
|
4493
4498
|
ranges: group.ranges.map(function (candidate) {
|
|
4494
4499
|
return _this10.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AvailabilityProjection, AvailabilityProjectionInput, AvailabilityQuery, AvailabilityQueryResult, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, GetProductTimeRangesRequest, ProductTimeRangeGroup } from './types';
|
|
1
|
+
import type { AvailabilityProjection, AvailabilityProjectionInput, AvailabilityQuery, AvailabilityQueryResult, AvailabilitySelectionValidationParams, AvailabilitySelectionValidationResult, GetProductTimeRangesRequest, GetProductTimeRangesRuntimeOptions, ProductTimeRangeGroup } from './types';
|
|
2
2
|
export declare function createAvailabilityProjection(input: AvailabilityProjectionInput): AvailabilityProjection;
|
|
3
|
-
export declare function getProductTimeRanges(projection: AvailabilityProjection, request?: GetProductTimeRangesRequest): ProductTimeRangeGroup[];
|
|
3
|
+
export declare function getProductTimeRanges(projection: AvailabilityProjection, request?: GetProductTimeRangesRequest, runtimeOptions?: GetProductTimeRangesRuntimeOptions): ProductTimeRangeGroup[];
|
|
4
4
|
export declare function queryAvailabilityProjection(projection: AvailabilityProjection, request: AvailabilityQuery): AvailabilityQueryResult;
|
|
5
5
|
export declare function validateAvailabilitySelection(projection: AvailabilityProjection, params: AvailabilitySelectionValidationParams): AvailabilitySelectionValidationResult;
|
|
@@ -88,6 +88,9 @@ function addMinutesZoned(value, minutes, _timezoneName) {
|
|
|
88
88
|
function ceilToTenMinutes(value, _timezoneName) {
|
|
89
89
|
return (0, _localClock.ceilLocalScalarToTenMinutes)(value);
|
|
90
90
|
}
|
|
91
|
+
function floorToMinute(value) {
|
|
92
|
+
return Math.floor(value / 60000) * 60000;
|
|
93
|
+
}
|
|
91
94
|
function nextDate(value, _timezoneName) {
|
|
92
95
|
return (0, _localClock.nextDate)(value);
|
|
93
96
|
}
|
|
@@ -880,6 +883,9 @@ function dedupeProductRanges(ranges) {
|
|
|
880
883
|
}
|
|
881
884
|
function createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes) {
|
|
882
885
|
const bookingEnd = addMinutesZoned(start, durationMinutes, projection.meta.timezone);
|
|
886
|
+
return createDurationTimeRangeWithEnd(product, start, bookingEnd, projection, fixedOffsetMinutes);
|
|
887
|
+
}
|
|
888
|
+
function createDurationTimeRangeWithEnd(product, start, bookingEnd, projection, fixedOffsetMinutes) {
|
|
883
889
|
return {
|
|
884
890
|
key: `${String(product.id)}:${start}:${bookingEnd}`,
|
|
885
891
|
productId: product.id,
|
|
@@ -895,7 +901,7 @@ function createDurationTimeRange(product, start, durationMinutes, projection, fi
|
|
|
895
901
|
scheduleRefs: []
|
|
896
902
|
};
|
|
897
903
|
}
|
|
898
|
-
function getProductTimeRanges(projection, request = {}) {
|
|
904
|
+
function getProductTimeRanges(projection, request = {}, runtimeOptions = {}) {
|
|
899
905
|
const normalizedPartySize = normalizePartySize(request.partySize);
|
|
900
906
|
const dateRange = resolveProjectionDateRange(projection, request.dateRange);
|
|
901
907
|
const slotStepMinutes = projection.meta.defaults.slotStepMinutes;
|
|
@@ -934,10 +940,29 @@ function getProductTimeRanges(projection, request = {}) {
|
|
|
934
940
|
})).reduce((current, ranges) => current === null ? ranges : intersectRangeLists(current, ranges), null) || [] : null;
|
|
935
941
|
const baseRanges = resourceRanges === null ? operatingRanges : intersectRangeLists(resourceRanges, operatingRanges);
|
|
936
942
|
const durationMinutes = resolveRequestedDurationMinutes(product, request);
|
|
943
|
+
const flexibleStartAt = (() => {
|
|
944
|
+
if (!product.isFlexibleDuration) return undefined;
|
|
945
|
+
const evaluatedAt = toDateTime(runtimeOptions.evaluatedAt || projection.meta.durationCandidateAnchorAt, projection.meta.timezone);
|
|
946
|
+
if (!Number.isFinite(evaluatedAt)) {
|
|
947
|
+
throw availabilityError('INVALID_TARGET_FILTER', 'runtimeOptions.evaluatedAt 必须是有效时间', {
|
|
948
|
+
evaluatedAt: runtimeOptions.evaluatedAt
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
return floorToMinute(evaluatedAt);
|
|
952
|
+
})();
|
|
937
953
|
const durationAnchor = ceilToTenMinutes(toDateTime(projection.meta.durationCandidateAnchorAt, projection.meta.timezone), projection.meta.timezone);
|
|
938
954
|
const requestedStartTimes = resolveRequestedDurationStartTimes(product, request);
|
|
939
955
|
const ranges = [];
|
|
940
956
|
baseRanges.forEach(range => {
|
|
957
|
+
if (product.isFlexibleDuration && flexibleStartAt !== undefined) {
|
|
958
|
+
const start = Math.max(range.start, flexibleStartAt);
|
|
959
|
+
if (start >= range.end) return;
|
|
960
|
+
const bookingDate = formatDate(start);
|
|
961
|
+
if (bookingDate >= dateRange.startDate && bookingDate <= dateRange.endDate) {
|
|
962
|
+
ranges.push(createDurationTimeRangeWithEnd(product, start, range.end, projection, fixedOffsetMinutes));
|
|
963
|
+
}
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
941
966
|
if (range.end <= durationAnchor) return;
|
|
942
967
|
let cursor = range.start;
|
|
943
968
|
if (cursor < durationAnchor) {
|
|
@@ -1593,6 +1618,8 @@ function queryAvailabilityProjection(projection, request) {
|
|
|
1593
1618
|
dateRange,
|
|
1594
1619
|
resourceIds: request.resourceIds,
|
|
1595
1620
|
partySize: normalizedPartySize
|
|
1621
|
+
}, {
|
|
1622
|
+
evaluatedAt
|
|
1596
1623
|
});
|
|
1597
1624
|
const candidateGroupMap = new Map(candidateGroups.map(group => [String(group.productId), group]));
|
|
1598
1625
|
if (request.target === 'date') {
|
|
@@ -81,6 +81,7 @@ export interface AvailabilityProduct {
|
|
|
81
81
|
id: AvailabilityId;
|
|
82
82
|
title?: string;
|
|
83
83
|
kind: AvailabilityProductKind;
|
|
84
|
+
isFlexibleDuration?: boolean;
|
|
84
85
|
durationMinutes?: number;
|
|
85
86
|
quantity?: number;
|
|
86
87
|
capacityRequired?: number;
|
|
@@ -240,6 +241,9 @@ export interface GetProductTimeRangesRequest {
|
|
|
240
241
|
*/
|
|
241
242
|
allowOutsideOperatingHoursForRequestedStartTimes?: boolean;
|
|
242
243
|
}
|
|
244
|
+
export interface GetProductTimeRangesRuntimeOptions {
|
|
245
|
+
evaluatedAt?: string;
|
|
246
|
+
}
|
|
243
247
|
export interface QueryAvailabilityBaseRequest {
|
|
244
248
|
productIds?: AvailabilityId[];
|
|
245
249
|
resourceIds?: 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 |
|
|
329
|
+
weekNum: 0 | 5 | 3 | 1 | 2 | 4 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "sold_out" | "lots_of_space" | "filling_up_fast";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -244,7 +244,7 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
244
244
|
private releaseAvailabilityCommitLock;
|
|
245
245
|
/** IO boundary: loads catalog, schedules, resources, occupancies, and registers one context. */
|
|
246
246
|
prepareAvailabilityProjection(params: UnifiedBookingSalesPrepareAvailabilityProjectionParams): Promise<AvailabilityContextRef>;
|
|
247
|
-
/**
|
|
247
|
+
/** Candidate calculation over the current context projection and runtime minute. */
|
|
248
248
|
getProductTimeRanges(contextId: string, request?: GetProductTimeRangesRequest): Promise<ContextualProductTimeRangeGroup[]>;
|
|
249
249
|
/** Thin facade: auto-refresh on cart drift, then delegate to the pure projection query. */
|
|
250
250
|
queryBookingAvailability(contextId: string, request: ContextualAvailabilityQuery): Promise<ContextualAvailabilityQueryResult>;
|
|
@@ -32,6 +32,7 @@ exports.normalizeProductForAvailability = normalizeProductForAvailability;
|
|
|
32
32
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
33
33
|
var _lodashEs = require("lodash-es");
|
|
34
34
|
var _modules = require("../../modules");
|
|
35
|
+
var _utils = require("../../modules/BookingContext/utils");
|
|
35
36
|
var _getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
|
|
36
37
|
var _ResourcePlanner = require("../../modules/ResourcePlanner");
|
|
37
38
|
var _types = require("./types");
|
|
@@ -503,6 +504,7 @@ function resolveProductScheduleItems(product, scheduleList) {
|
|
|
503
504
|
function normalizeProductForAvailability(product, scheduleList = [], fixedOffsetMinutes = (0, _localClock.captureRuntimeOffsetMinutes)()) {
|
|
504
505
|
const raw = product;
|
|
505
506
|
const kind = resolveProductKind(raw);
|
|
507
|
+
const isFlexibleDuration = kind === 'duration' && (0, _utils.isProductFlexibleDuration)(raw.duration);
|
|
506
508
|
const sessionRules = [];
|
|
507
509
|
const sessionRanges = [];
|
|
508
510
|
const explicitSession = raw.cartDetailValue?.session || raw._extend?.other?.session || raw.session;
|
|
@@ -524,7 +526,8 @@ function normalizeProductForAvailability(product, scheduleList = [], fixedOffset
|
|
|
524
526
|
id: raw.id ?? raw.product_id,
|
|
525
527
|
title: pickLocalizedText(raw.title || raw.name || raw.product_title),
|
|
526
528
|
kind,
|
|
527
|
-
|
|
529
|
+
isFlexibleDuration: isFlexibleDuration || undefined,
|
|
530
|
+
durationMinutes: kind === 'duration' && !isFlexibleDuration ? Math.max(1, Number(raw.duration?.value || raw.duration || raw.service_duration || 30) || 30) : undefined,
|
|
528
531
|
requirementGroups: normalizeRequirementGroups(raw),
|
|
529
532
|
sessionRules,
|
|
530
533
|
sessionRanges,
|
|
@@ -2919,7 +2922,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
2919
2922
|
return handle;
|
|
2920
2923
|
}
|
|
2921
2924
|
|
|
2922
|
-
/**
|
|
2925
|
+
/** Candidate calculation over the current context projection and runtime minute. */
|
|
2923
2926
|
async getProductTimeRanges(contextId, request = {}) {
|
|
2924
2927
|
const {
|
|
2925
2928
|
context,
|
|
@@ -2932,6 +2935,8 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
2932
2935
|
...(allowOutsideOperatingHoursForRequestedStartTimes ? {
|
|
2933
2936
|
allowOutsideOperatingHoursForRequestedStartTimes: true
|
|
2934
2937
|
} : {})
|
|
2938
|
+
}, {
|
|
2939
|
+
evaluatedAt: this.getAvailabilityRuntimeDateTime()
|
|
2935
2940
|
}).map(group => ({
|
|
2936
2941
|
...group,
|
|
2937
2942
|
ranges: group.ranges.map(candidate => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
|