@happychef/algorithm 1.0.2 → 1.0.4
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.
|
@@ -29,9 +29,10 @@ function parseDateTimeInTimeZone(dateStr, timeStr, timeZone) {
|
|
|
29
29
|
* @param {Array} reservations - An array of reservation objects.
|
|
30
30
|
* @param {number} guests - The number of guests for the reservation.
|
|
31
31
|
* @param {Array} blockedSlots - Optional array of blocked time slots to exclude.
|
|
32
|
+
* @param {string|null} giftcard - Optional giftcard to filter times by meal.
|
|
32
33
|
* @returns {Object} - Returns a pruned object of available time blocks or shifts, or an empty object if out of range.
|
|
33
34
|
*/
|
|
34
|
-
function getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlots = []) {
|
|
35
|
+
function getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlots = [], giftcard = null) {
|
|
35
36
|
// Get 'uurOpVoorhand' from general settings
|
|
36
37
|
let uurOpVoorhand = 4;
|
|
37
38
|
if (
|
|
@@ -84,7 +85,7 @@ function getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlot
|
|
|
84
85
|
currentTimeInTimeZone.toDateString() === targetDateInTimeZone.toDateString();
|
|
85
86
|
|
|
86
87
|
// Get available time blocks or shifts
|
|
87
|
-
const availableTimeblocks = timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots);
|
|
88
|
+
const availableTimeblocks = timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots, giftcard);
|
|
88
89
|
|
|
89
90
|
// If the date is today and uurOpVoorhand is greater than zero, prune time blocks
|
|
90
91
|
if (isToday && uurOpVoorhand >= 0) {
|
package/isDateAvailable.js
CHANGED
|
@@ -58,16 +58,17 @@ function isDateWithinAllowedRange(data, dateStr) {
|
|
|
58
58
|
* @param {Array} reservations - An array of reservation objects.
|
|
59
59
|
* @param {number} guests - The number of guests for the reservation.
|
|
60
60
|
* @param {Array} blockedSlots - Optional array of blocked time slots to exclude.
|
|
61
|
+
* @param {string|null} giftcard - Optional giftcard to filter times by meal.
|
|
61
62
|
* @returns {boolean} - Returns true if the date has at least one available timeblock, false otherwise.
|
|
62
63
|
*/
|
|
63
|
-
function isDateAvailable(data, dateStr, reservations, guests, blockedSlots = []) {
|
|
64
|
+
function isDateAvailable(data, dateStr, reservations, guests, blockedSlots = [], giftcard = null) {
|
|
64
65
|
// Check if date is within allowed range
|
|
65
66
|
if (!isDateWithinAllowedRange(data, dateStr)) {
|
|
66
67
|
return false;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
// Get available timeblocks using the existing logic
|
|
70
|
-
const availableTimeblocks = getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlots);
|
|
71
|
+
const availableTimeblocks = getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlots, giftcard);
|
|
71
72
|
|
|
72
73
|
// Return true only if we have at least one available timeblock
|
|
73
74
|
return Object.keys(availableTimeblocks).length > 0;
|
|
@@ -69,10 +69,11 @@ function timeHasGiftcard(data, dateStr, timeStr, giftcard) {
|
|
|
69
69
|
* @param {string} dateStr - The date string in "YYYY-MM-DD" format.
|
|
70
70
|
* @param {Array} reservations - An array of reservation objects.
|
|
71
71
|
* @param {number} guests - The number of guests for the reservation.
|
|
72
|
+
* @param {Array} blockedSlots - Optional array of blocked time slots to exclude.
|
|
72
73
|
* @param {string|null} selectedGiftcard - The selected giftcard (if any).
|
|
73
74
|
* @returns {boolean} - Returns true if the date passes all checks to be available.
|
|
74
75
|
*/
|
|
75
|
-
function isDateAvailableWithTableCheck(data, dateStr, reservations, guests, selectedGiftcard) {
|
|
76
|
+
function isDateAvailableWithTableCheck(data, dateStr, reservations, guests, blockedSlots = [], selectedGiftcard = null) {
|
|
76
77
|
// 0) Optionally filter by selected menu item's date range (only when normalOpeningTimes = false)
|
|
77
78
|
const currentItem = typeof window !== 'undefined' ? window.currentReservationTicketItem : null;
|
|
78
79
|
if (
|
|
@@ -112,7 +113,7 @@ function isDateAvailableWithTableCheck(data, dateStr, reservations, guests, sele
|
|
|
112
113
|
console.log(`Table assignment is ${isTableAssignmentEnabled ? 'ENABLED' : 'DISABLED'} for date ${dateStr}`);
|
|
113
114
|
|
|
114
115
|
// 1) First, do the standard day-level checks (including simple giftcard check).
|
|
115
|
-
const basicDateAvailable = isDateAvailable(data, dateStr, reservations, guests, selectedGiftcard);
|
|
116
|
+
const basicDateAvailable = isDateAvailable(data, dateStr, reservations, guests, blockedSlots, selectedGiftcard);
|
|
116
117
|
if (!basicDateAvailable) {
|
|
117
118
|
console.log(`Date ${dateStr} fails basic availability check`);
|
|
118
119
|
return false;
|
|
@@ -126,7 +127,7 @@ function isDateAvailableWithTableCheck(data, dateStr, reservations, guests, sele
|
|
|
126
127
|
|
|
127
128
|
// 2) Get all available timeblocks for this date
|
|
128
129
|
console.log(`Getting available timeblocks for ${dateStr}`);
|
|
129
|
-
const availableTimeblocks = getAvailableTimeblocks(data, dateStr, reservations, guests);
|
|
130
|
+
const availableTimeblocks = getAvailableTimeblocks(data, dateStr, reservations, guests, blockedSlots, selectedGiftcard);
|
|
130
131
|
console.log(`Found ${Object.keys(availableTimeblocks).length} available timeblocks before table check`);
|
|
131
132
|
|
|
132
133
|
// If no timeblocks are available at all, exit early
|
package/isTimeAvailable.js
CHANGED
|
@@ -8,11 +8,12 @@ const { timeblocksAvailable } = require('./processing/timeblocksAvailable');
|
|
|
8
8
|
* @param {Array} reservations - An array of existing reservation objects.
|
|
9
9
|
* @param {number} guests - The number of guests for the new reservation request.
|
|
10
10
|
* @param {Array} blockedSlots - Optional array of blocked time slots to exclude.
|
|
11
|
+
* @param {string|null} giftcard - Optional giftcard to filter times by meal.
|
|
11
12
|
* @returns {boolean} - Returns true if the time is available, false otherwise.
|
|
12
13
|
*/
|
|
13
|
-
function isTimeAvailable(data, dateStr, timeStr, reservations, guests, blockedSlots = []) {
|
|
14
|
+
function isTimeAvailable(data, dateStr, timeStr, reservations, guests, blockedSlots = [], giftcard = null) {
|
|
14
15
|
// Get all available timeblocks for the specified date and guest count
|
|
15
|
-
const availableTimeblocks = timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots);
|
|
16
|
+
const availableTimeblocks = timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots, giftcard);
|
|
16
17
|
|
|
17
18
|
// Check if the specific timeStr is one of the available keys
|
|
18
19
|
return Object.prototype.hasOwnProperty.call(availableTimeblocks, timeStr);
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const { getDailyGuestCounts } = require('./dailyGuestCounts');
|
|
2
2
|
const { getMealTypesWithShifts } = require('./mealTypeCount');
|
|
3
3
|
const { getDataByDateAndMealWithExceptions } = require('../restaurant_data/exceptions');
|
|
4
|
-
const { getMealTypeByTime, parseTime: parseTimeOH } = require('../restaurant_data/openinghours');
|
|
4
|
+
const { getMealTypeByTime, parseTime: parseTimeOH, daysOfWeekEnglish } = require('../restaurant_data/openinghours');
|
|
5
|
+
const moment = require('moment-timezone');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Parses a time string in "HH:MM" format into minutes since midnight.
|
|
@@ -38,6 +39,36 @@ function getDuurReservatie(data) {
|
|
|
38
39
|
return duurReservatie;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Checks if a time slot belongs to a meal that has the selected giftcard enabled.
|
|
44
|
+
*/
|
|
45
|
+
function timeHasGiftcard(data, dateStr, timeStr, giftcard) {
|
|
46
|
+
if (!giftcard || (typeof giftcard === 'string' && !giftcard.trim())) {
|
|
47
|
+
return true; // No giftcard => no restriction
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const mealType = getMealTypeByTime(timeStr);
|
|
51
|
+
if (!mealType) return false;
|
|
52
|
+
|
|
53
|
+
const m = moment.tz(dateStr, 'YYYY-MM-DD', 'Europe/Brussels');
|
|
54
|
+
if (!m.isValid()) return false;
|
|
55
|
+
const englishDay = daysOfWeekEnglish[m.day()];
|
|
56
|
+
|
|
57
|
+
const ohKey = `openinghours-${mealType}`;
|
|
58
|
+
const daySettings =
|
|
59
|
+
data[ohKey] &&
|
|
60
|
+
data[ohKey].schemeSettings &&
|
|
61
|
+
data[ohKey].schemeSettings[englishDay]
|
|
62
|
+
? data[ohKey].schemeSettings[englishDay]
|
|
63
|
+
: null;
|
|
64
|
+
|
|
65
|
+
if (!daySettings) return false;
|
|
66
|
+
if (daySettings.giftcardsEnabled !== true) return false;
|
|
67
|
+
if (!Array.isArray(daySettings.giftcards) || daySettings.giftcards.length === 0) return false;
|
|
68
|
+
|
|
69
|
+
return daySettings.giftcards.includes(giftcard);
|
|
70
|
+
}
|
|
71
|
+
|
|
41
72
|
/**
|
|
42
73
|
* Determines if a given start time plus duurReservatie fits within the meal timeframe.
|
|
43
74
|
*/
|
|
@@ -58,7 +89,7 @@ function fitsWithinMeal(data, dateStr, startTimeStr, duurReservatie) {
|
|
|
58
89
|
return startTime >= mealStartTime && startTime + duurReservatie <= mealEndTime;
|
|
59
90
|
}
|
|
60
91
|
|
|
61
|
-
function timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots = []) {
|
|
92
|
+
function timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots = [], giftcard = null) {
|
|
62
93
|
const duurReservatie = getDuurReservatie(data);
|
|
63
94
|
const intervalReservatie = getInterval(data);
|
|
64
95
|
|
|
@@ -76,7 +107,10 @@ function timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots =
|
|
|
76
107
|
for (const shift of shiftsInfo) {
|
|
77
108
|
const { time, availableSeats } = shift;
|
|
78
109
|
if (availableSeats >= guests && fitsWithinMeal(data, dateStr, time, duurReservatie)) {
|
|
79
|
-
|
|
110
|
+
// Check if time matches giftcard requirement
|
|
111
|
+
if (timeHasGiftcard(data, dateStr, time, giftcard)) {
|
|
112
|
+
availableTimeblocks[time] = { name: time };
|
|
113
|
+
}
|
|
80
114
|
}
|
|
81
115
|
}
|
|
82
116
|
}
|
|
@@ -107,7 +141,10 @@ function timeblocksAvailable(data, dateStr, reservations, guests, blockedSlots =
|
|
|
107
141
|
|
|
108
142
|
// If all consecutive slots are available, check if the full duration fits
|
|
109
143
|
if (consecutiveSlotsAvailable && fitsWithinMeal(data, dateStr, timeSlots[i], duurReservatie)) {
|
|
110
|
-
|
|
144
|
+
// Check if time matches giftcard requirement
|
|
145
|
+
if (timeHasGiftcard(data, dateStr, timeSlots[i], giftcard)) {
|
|
146
|
+
availableTimeblocks[timeSlots[i]] = { name: timeSlots[i] };
|
|
147
|
+
}
|
|
111
148
|
}
|
|
112
149
|
}
|
|
113
150
|
}
|