@pisell/pisellos 2.3.99 → 2.3.101
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/modules/Rules/index.d.ts +5 -0
- package/dist/modules/Rules/index.js +27 -12
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- 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/modules/Rules/index.d.ts +5 -0
- package/lib/modules/Rules/index.js +20 -11
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- 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[];
|
|
@@ -14,6 +14,11 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
14
14
|
setRulesList(rulesList: Rules[]): Promise<void>;
|
|
15
15
|
getRulesList(): Rules[];
|
|
16
16
|
getWalletPassEvaluator(): import("../..").WalletPassEvaluator | undefined;
|
|
17
|
+
private normalizeHolderRecordIds;
|
|
18
|
+
/**
|
|
19
|
+
* 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
|
|
20
|
+
* required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
|
|
21
|
+
*/
|
|
17
22
|
private checkHolderMatch;
|
|
18
23
|
isDiscountListAvailable({ oldDiscountList, newDiscountList, productList, orderTotalAmount, holders, isFormSubject, }: {
|
|
19
24
|
oldDiscountList: Discount[];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
var _excluded = ["_original_add_price"],
|
|
2
2
|
_excluded2 = ["_original_price", "_original_add_price"];
|
|
3
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
3
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
5
4
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
6
5
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -12,6 +11,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
12
11
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
13
12
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
14
13
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
14
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
15
15
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
16
16
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
17
17
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
@@ -109,24 +109,39 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
109
109
|
var _this$window$getWalle, _this$window;
|
|
110
110
|
return (_this$window$getWalle = (_this$window = this.window).getWalletPassEvaluator) === null || _this$window$getWalle === void 0 ? void 0 : _this$window$getWalle.call(_this$window);
|
|
111
111
|
}
|
|
112
|
+
}, {
|
|
113
|
+
key: "normalizeHolderRecordIds",
|
|
114
|
+
value: function normalizeHolderRecordIds(value) {
|
|
115
|
+
var records = Array.isArray(value) ? value : [value];
|
|
116
|
+
return Array.from(new Set(records.map(function (record) {
|
|
117
|
+
if (record && _typeof(record) === 'object') {
|
|
118
|
+
return record.form_record_id;
|
|
119
|
+
}
|
|
120
|
+
return record;
|
|
121
|
+
}).filter(function (record) {
|
|
122
|
+
return record !== undefined && record !== null && record !== '' && record !== 0 && record !== '0';
|
|
123
|
+
}).map(String)));
|
|
124
|
+
}
|
|
112
125
|
|
|
113
|
-
|
|
126
|
+
/**
|
|
127
|
+
* 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
|
|
128
|
+
* required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
|
|
129
|
+
*/
|
|
114
130
|
}, {
|
|
115
131
|
key: "checkHolderMatch",
|
|
116
132
|
value: function checkHolderMatch(discount, product, holders) {
|
|
117
133
|
var _discount$holder;
|
|
118
134
|
// 非表单类型 holder 视为匹配
|
|
119
135
|
if (((_discount$holder = discount.holder) === null || _discount$holder === void 0 ? void 0 : _discount$holder.holder_type) !== 'form') return true;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
var
|
|
123
|
-
var
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return (productHolderId || orderHolderId) === discount.holder.holder_id;
|
|
136
|
+
var discountHolderIds = this.normalizeHolderRecordIds(discount.holder.holder_id);
|
|
137
|
+
if (!discountHolderIds.length) return false;
|
|
138
|
+
var productHolderIds = this.normalizeHolderRecordIds(product.holder_id);
|
|
139
|
+
var candidateHolderIds = productHolderIds.length ? productHolderIds : this.normalizeHolderRecordIds(holders);
|
|
140
|
+
if (!candidateHolderIds.length) return false;
|
|
141
|
+
var discountHolderIdSet = new Set(discountHolderIds);
|
|
142
|
+
return candidateHolderIds.some(function (holderId) {
|
|
143
|
+
return discountHolderIdSet.has(holderId);
|
|
144
|
+
});
|
|
130
145
|
}
|
|
131
146
|
|
|
132
147
|
// 判断discountList 是否可以对当前productList生效
|
|
@@ -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 | 1 | 2 | 6 | 4 | 5 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -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[];
|
|
@@ -14,6 +14,11 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
14
14
|
setRulesList(rulesList: Rules[]): Promise<void>;
|
|
15
15
|
getRulesList(): Rules[];
|
|
16
16
|
getWalletPassEvaluator(): import("../..").WalletPassEvaluator | undefined;
|
|
17
|
+
private normalizeHolderRecordIds;
|
|
18
|
+
/**
|
|
19
|
+
* 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
|
|
20
|
+
* required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
|
|
21
|
+
*/
|
|
17
22
|
private checkHolderMatch;
|
|
18
23
|
isDiscountListAvailable({ oldDiscountList, newDiscountList, productList, orderTotalAmount, holders, isFormSubject, }: {
|
|
19
24
|
oldDiscountList: Discount[];
|
|
@@ -38,21 +38,30 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
38
38
|
getWalletPassEvaluator() {
|
|
39
39
|
return this.window.getWalletPassEvaluator?.();
|
|
40
40
|
}
|
|
41
|
+
normalizeHolderRecordIds(value) {
|
|
42
|
+
const records = Array.isArray(value) ? value : [value];
|
|
43
|
+
return Array.from(new Set(records.map(record => {
|
|
44
|
+
if (record && typeof record === 'object') {
|
|
45
|
+
return record.form_record_id;
|
|
46
|
+
}
|
|
47
|
+
return record;
|
|
48
|
+
}).filter(record => record !== undefined && record !== null && record !== '' && record !== 0 && record !== '0').map(String)));
|
|
49
|
+
}
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
/**
|
|
52
|
+
* 特定 form Holder 卡只授权给绑定同一 Holder Record 的商品行。
|
|
53
|
+
* required/isNeedHolder 仅控制是否强制选择 Holder,不参与优惠资格。
|
|
54
|
+
*/
|
|
43
55
|
checkHolderMatch(discount, product, holders) {
|
|
44
56
|
// 非表单类型 holder 视为匹配
|
|
45
57
|
if (discount.holder?.holder_type !== 'form') return true;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!orderHolderId && !productHolderId) return false;
|
|
54
|
-
// 最终直接匹配 holder 是否相同
|
|
55
|
-
return (productHolderId || orderHolderId) === discount.holder.holder_id;
|
|
58
|
+
const discountHolderIds = this.normalizeHolderRecordIds(discount.holder.holder_id);
|
|
59
|
+
if (!discountHolderIds.length) return false;
|
|
60
|
+
const productHolderIds = this.normalizeHolderRecordIds(product.holder_id);
|
|
61
|
+
const candidateHolderIds = productHolderIds.length ? productHolderIds : this.normalizeHolderRecordIds(holders);
|
|
62
|
+
if (!candidateHolderIds.length) return false;
|
|
63
|
+
const discountHolderIdSet = new Set(discountHolderIds);
|
|
64
|
+
return candidateHolderIds.some(holderId => discountHolderIdSet.has(holderId));
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
// 判断discountList 是否可以对当前productList生效
|
|
@@ -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 | 1 | 2 | 6 | 4 | 5 | 3;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -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))
|