@final-commerce/common 2.4.0-staging.1 → 2.4.0-staging.2
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/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +33 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -9
- package/dist/index.mjs.map +1 -1
- package/dist/pos-types/index.d.mts +3 -0
- package/dist/pos-types/index.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3051,6 +3051,18 @@ var stateFor = (hasShift, offerable, free) => {
|
|
|
3051
3051
|
}
|
|
3052
3052
|
return free === 0 ? "fullyBooked" /* FULLY_BOOKED */ : "available" /* AVAILABLE */;
|
|
3053
3053
|
};
|
|
3054
|
+
function shopDayKey(instant, timeZone) {
|
|
3055
|
+
const { year, month, day } = zonedParts(instant, timeZone);
|
|
3056
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
3057
|
+
return `${year}-${pad(month)}-${pad(day)}`;
|
|
3058
|
+
}
|
|
3059
|
+
function shopDayRange(fromDayKey, count, timeZone) {
|
|
3060
|
+
const [year, month, day] = fromDayKey.split("-").map(Number);
|
|
3061
|
+
return {
|
|
3062
|
+
from: instantFromLocal(year, month, day, 0, timeZone),
|
|
3063
|
+
to: instantFromLocal(year, month, day + Math.max(1, count), 0, timeZone)
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3054
3066
|
function buildAvailability({
|
|
3055
3067
|
productId,
|
|
3056
3068
|
bookingRulesId,
|
|
@@ -3088,20 +3100,20 @@ function buildAvailability({
|
|
|
3088
3100
|
const grids = resources.map((resource) => {
|
|
3089
3101
|
const mine = byResource.get(resource.id) ?? [];
|
|
3090
3102
|
const busy = (resource.seats ?? 1) === 1 ? mine : [];
|
|
3091
|
-
const
|
|
3103
|
+
const slots2 = buildGrid(rule, resource.timeZone, from, to, now, busy).filter(
|
|
3092
3104
|
(slot) => withinPresence(slot, resource.timeZone, resource.presence)
|
|
3093
3105
|
);
|
|
3094
|
-
return { resource, slots };
|
|
3106
|
+
return { resource, slots: slots2 };
|
|
3095
3107
|
});
|
|
3096
3108
|
const byInstant = /* @__PURE__ */ new Map();
|
|
3097
3109
|
const freeSlotsPerResource = /* @__PURE__ */ new Map();
|
|
3098
|
-
for (const { resource, slots } of grids) {
|
|
3110
|
+
for (const { resource, slots: slots2 } of grids) {
|
|
3099
3111
|
const capacity = resource.seats ?? 1;
|
|
3100
3112
|
const mine = byResource.get(resource.id) ?? [];
|
|
3101
|
-
for (const slot of
|
|
3113
|
+
for (const slot of slots2) {
|
|
3102
3114
|
const { taken, foreignProductId } = occupancyIn(mine, productId, slot.startAt, slot.bufferEndAt, shared);
|
|
3103
3115
|
const free = foreignProductId ? 0 : Math.max(capacity - taken, 0);
|
|
3104
|
-
const entry = byInstant.get(+slot.startAt) ?? { ...slot, capacity: 0, booked: 0, free: 0, resources: [] };
|
|
3116
|
+
const entry = byInstant.get(+slot.startAt) ?? { ...slot, capacity: 0, booked: 0, free: 0, resources: [], dayKey: shopDayKey(slot.startAt, resource.timeZone) };
|
|
3105
3117
|
entry.capacity += capacity;
|
|
3106
3118
|
entry.booked += foreignProductId ? capacity : taken;
|
|
3107
3119
|
entry.free += free;
|
|
@@ -3111,27 +3123,35 @@ function buildAvailability({
|
|
|
3111
3123
|
byInstant.set(+slot.startAt, entry);
|
|
3112
3124
|
}
|
|
3113
3125
|
}
|
|
3114
|
-
const inWindow = grids.map(({ resource, slots }) => {
|
|
3126
|
+
const inWindow = grids.map(({ resource, slots: slots2 }) => {
|
|
3115
3127
|
const free = freeSlotsPerResource.get(resource.id) ?? 0;
|
|
3116
3128
|
return {
|
|
3117
3129
|
resourceId: resource.id,
|
|
3118
3130
|
name: resource.name,
|
|
3119
|
-
slots:
|
|
3131
|
+
slots: slots2.length,
|
|
3120
3132
|
free,
|
|
3121
3133
|
// Lazily: the shift grid is a second walk, and only an empty answer needs it.
|
|
3122
3134
|
state: stateFor(
|
|
3123
3135
|
() => buildGrid(rule, resource.timeZone, from, to, now).filter(
|
|
3124
3136
|
(slot) => withinPresence(slot, resource.timeZone, resource.presence)
|
|
3125
3137
|
).length > 0,
|
|
3126
|
-
|
|
3138
|
+
slots2.length,
|
|
3127
3139
|
free
|
|
3128
3140
|
)
|
|
3129
3141
|
};
|
|
3130
3142
|
});
|
|
3143
|
+
const slots = [...byInstant.values()].sort((first, second) => +first.startAt - +second.startAt);
|
|
3131
3144
|
return {
|
|
3132
3145
|
...header,
|
|
3133
3146
|
resources: inWindow,
|
|
3134
|
-
slots
|
|
3147
|
+
slots,
|
|
3148
|
+
/**
|
|
3149
|
+
* The clock every instant above reads on. Returned rather than assumed: without it a caller
|
|
3150
|
+
* has to fetch the zone from somewhere else and hope it is the same one the grid used.
|
|
3151
|
+
*/
|
|
3152
|
+
timeZone: resources[0]?.timeZone ?? null,
|
|
3153
|
+
/** The shop days this answer covers, in order — what a day picker lists. */
|
|
3154
|
+
days: [...new Set(slots.map((slot) => slot.dayKey))]
|
|
3135
3155
|
};
|
|
3136
3156
|
}
|
|
3137
3157
|
function presentAt(resources, rows, outletId) {
|
|
@@ -3326,6 +3346,8 @@ export {
|
|
|
3326
3346
|
roundToPrecision,
|
|
3327
3347
|
sameFamily,
|
|
3328
3348
|
setOrderState,
|
|
3349
|
+
shopDayKey,
|
|
3350
|
+
shopDayRange,
|
|
3329
3351
|
signReportForDisplay,
|
|
3330
3352
|
slotsForWindow,
|
|
3331
3353
|
stringifyMinorUnits,
|