@saltcorn/reservable 0.3.1 → 0.3.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/common.js +32 -2
- package/package.json +1 -1
- package/table-provider.js +37 -19
package/common.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const Table = require("@saltcorn/data/models/table");
|
|
2
|
+
|
|
1
3
|
const gcd = function (a, b) {
|
|
2
4
|
if (!b) {
|
|
3
5
|
return a;
|
|
@@ -27,6 +29,7 @@ const get_available_slots = async ({
|
|
|
27
29
|
services,
|
|
28
30
|
start_field,
|
|
29
31
|
duration_field,
|
|
32
|
+
expand_entities,
|
|
30
33
|
}) => {
|
|
31
34
|
const from = new Date(date);
|
|
32
35
|
from.setHours(0, 0, 0, 0);
|
|
@@ -38,6 +41,19 @@ const get_available_slots = async ({
|
|
|
38
41
|
q[reservable_entity_key] = entity_wanted;
|
|
39
42
|
//console.log(JSON.stringify({ date, q }, null, 2));
|
|
40
43
|
const taken_slots = await table.getRows(q);
|
|
44
|
+
let ents = [];
|
|
45
|
+
let entTable;
|
|
46
|
+
let entityTablePK;
|
|
47
|
+
const available_entity_slots = {};
|
|
48
|
+
if (reservable_entity_key && !entity_wanted && expand_entities) {
|
|
49
|
+
const entKey = table.getField(reservable_entity_key);
|
|
50
|
+
entTable = Table.findOne(entKey.reftable_name);
|
|
51
|
+
ents = await entTable.getRows();
|
|
52
|
+
entityTablePK = entTable.pk_name;
|
|
53
|
+
ents.forEach((e) => {
|
|
54
|
+
available_entity_slots[e[entityTablePK]] = [];
|
|
55
|
+
});
|
|
56
|
+
}
|
|
41
57
|
|
|
42
58
|
// figure out regular availability for this day
|
|
43
59
|
const dayOfWeek = [
|
|
@@ -56,10 +72,13 @@ const get_available_slots = async ({
|
|
|
56
72
|
);
|
|
57
73
|
|
|
58
74
|
const available_slots = [];
|
|
59
|
-
const durGCD = gcdArr(services.map((s) => s.duration));
|
|
75
|
+
const durGCD = gcdArr([60, ...services.map((s) => s.duration)]);
|
|
60
76
|
relevant_availabilities.forEach(({ from, to }) => {
|
|
61
77
|
for (let i = (from * 60) / durGCD; i < (to * 60) / durGCD; i++) {
|
|
62
78
|
available_slots[i] = true;
|
|
79
|
+
ents.forEach((e) => {
|
|
80
|
+
available_entity_slots[e[entityTablePK]][i] = true;
|
|
81
|
+
});
|
|
63
82
|
}
|
|
64
83
|
});
|
|
65
84
|
//console.log({ taken_slots });
|
|
@@ -75,9 +94,20 @@ const get_available_slots = async ({
|
|
|
75
94
|
const to = from + slot[duration_field];
|
|
76
95
|
for (let i = from / durGCD; i < to / durGCD; i++) {
|
|
77
96
|
available_slots[i] = false;
|
|
97
|
+
ents.forEach((e) => {
|
|
98
|
+
available_entity_slots[e[entityTablePK]][i] = false;
|
|
99
|
+
});
|
|
78
100
|
}
|
|
79
101
|
});
|
|
80
|
-
return {
|
|
102
|
+
return {
|
|
103
|
+
available_slots,
|
|
104
|
+
available_entity_slots,
|
|
105
|
+
from,
|
|
106
|
+
durGCD,
|
|
107
|
+
taken_slots,
|
|
108
|
+
entities: ents,
|
|
109
|
+
entityTablePK,
|
|
110
|
+
};
|
|
81
111
|
};
|
|
82
112
|
|
|
83
113
|
module.exports = { get_available_slots, range };
|
package/package.json
CHANGED
package/table-provider.js
CHANGED
|
@@ -236,17 +236,26 @@ module.exports = {
|
|
|
236
236
|
const services = where?.service
|
|
237
237
|
? cfg.services.filter((s) => s.title === where.service)
|
|
238
238
|
: cfg.services;
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
239
|
+
const expand_entities = !where?.entity && cfg.reservable_entity_key;
|
|
240
|
+
const {
|
|
241
|
+
available_slots,
|
|
242
|
+
from,
|
|
243
|
+
durGCD,
|
|
244
|
+
taken_slots,
|
|
245
|
+
available_entity_slots,
|
|
246
|
+
entities,
|
|
247
|
+
entityTablePK,
|
|
248
|
+
} = await get_available_slots({
|
|
249
|
+
table,
|
|
250
|
+
date,
|
|
251
|
+
availability: cfg.availability,
|
|
252
|
+
entity_wanted: where?.entity || undefined,
|
|
253
|
+
reservable_entity_key: cfg.reservable_entity_key,
|
|
254
|
+
start_field: cfg.start_field,
|
|
255
|
+
duration_field: cfg.duration_field,
|
|
256
|
+
services,
|
|
257
|
+
expand_entities,
|
|
258
|
+
});
|
|
250
259
|
const minSlot = Math.min(...Object.keys(available_slots));
|
|
251
260
|
const maxSlot = Math.max(...Object.keys(available_slots));
|
|
252
261
|
const service_availabilities = services.map((service, serviceIx) => {
|
|
@@ -263,17 +272,21 @@ module.exports = {
|
|
|
263
272
|
date1.setSeconds(0);
|
|
264
273
|
date1.setMilliseconds(0);
|
|
265
274
|
if (date1 > new Date())
|
|
266
|
-
if (
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
275
|
+
if (expand_entities)
|
|
276
|
+
entities.forEach((e) => {
|
|
277
|
+
availabilities.push({
|
|
278
|
+
date: date1,
|
|
279
|
+
available: range(nslots, i).every(
|
|
280
|
+
(j) => available_entity_slots[e[entityTablePK]][j]
|
|
281
|
+
),
|
|
282
|
+
entity: e[entityTablePK],
|
|
283
|
+
});
|
|
270
284
|
});
|
|
271
|
-
|
|
285
|
+
else
|
|
272
286
|
availabilities.push({
|
|
273
287
|
date: date1,
|
|
274
|
-
available:
|
|
288
|
+
available: range(nslots, i).every((j) => available_slots[j]),
|
|
275
289
|
});
|
|
276
|
-
}
|
|
277
290
|
}
|
|
278
291
|
//console.log({ availabilities, service });
|
|
279
292
|
return { availabilities, service, serviceIx };
|
|
@@ -283,7 +296,7 @@ module.exports = {
|
|
|
283
296
|
.map(({ availabilities, service, serviceIx }) =>
|
|
284
297
|
availabilities
|
|
285
298
|
.filter((a) => a.available)
|
|
286
|
-
.map(({ date }) => {
|
|
299
|
+
.map(({ date, entity }) => {
|
|
287
300
|
return {
|
|
288
301
|
id: `${date.toISOString()}//${service.title}`,
|
|
289
302
|
service: service.title,
|
|
@@ -292,6 +305,11 @@ module.exports = {
|
|
|
292
305
|
start_date: date,
|
|
293
306
|
start_hour: date.getHours(),
|
|
294
307
|
start_minute: date.getMinutes(),
|
|
308
|
+
...(where?.entity
|
|
309
|
+
? { entity: where.entity }
|
|
310
|
+
: entity
|
|
311
|
+
? { entity }
|
|
312
|
+
: {}),
|
|
295
313
|
};
|
|
296
314
|
})
|
|
297
315
|
)
|