@happychef/algorithm 1.2.30 → 1.3.0

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.
Files changed (56) hide show
  1. package/.github/workflows/ci-cd.yml +80 -80
  2. package/CHANGELOG.md +8 -8
  3. package/RESERVERINGEN_GIDS.md +986 -986
  4. package/assignTables.js +444 -456
  5. package/changes/2025/December/PR2___change.md +14 -14
  6. package/changes/2025/December/PR3_add__change.md +20 -20
  7. package/changes/2025/December/PR4___.md +15 -15
  8. package/changes/2025/December/PR5___.md +15 -15
  9. package/changes/2025/December/PR6__del_.md +17 -17
  10. package/changes/2025/December/PR7_add__change.md +21 -21
  11. package/changes/2026/February/PR15_add__change.md +22 -0
  12. package/changes/2026/February/PR16_add_getDateClosingReasons.md +31 -0
  13. package/changes/2026/January/PR10_add__change.md +21 -21
  14. package/changes/2026/January/PR11_add__change.md +19 -19
  15. package/changes/2026/January/PR12_add__.md +21 -21
  16. package/changes/2026/January/PR13_add__change.md +20 -20
  17. package/changes/2026/January/PR14_add__change.md +19 -19
  18. package/changes/2026/January/PR8_add__change.md +38 -38
  19. package/changes/2026/January/PR9_add__change.md +19 -19
  20. package/filters/maxArrivalsFilter.js +114 -114
  21. package/filters/maxGroupsFilter.js +221 -221
  22. package/filters/timeFilter.js +89 -89
  23. package/getAvailableTimeblocks.js +158 -158
  24. package/getDateClosingReasons.js +193 -0
  25. package/grouping.js +162 -162
  26. package/index.js +43 -42
  27. package/isDateAvailable.js +80 -80
  28. package/isDateAvailableWithTableCheck.js +172 -172
  29. package/isTimeAvailable.js +26 -26
  30. package/package.json +27 -27
  31. package/processing/dailyGuestCounts.js +73 -73
  32. package/processing/mealTypeCount.js +133 -133
  33. package/processing/timeblocksAvailable.js +182 -182
  34. package/reservation_data/counter.js +74 -74
  35. package/restaurant_data/exceptions.js +150 -150
  36. package/restaurant_data/openinghours.js +142 -139
  37. package/simulateTableAssignment.js +726 -726
  38. package/tableHelpers.js +209 -206
  39. package/tables/time/parseTime.js +19 -19
  40. package/tables/time/shifts.js +7 -7
  41. package/tables/utils/calculateDistance.js +13 -13
  42. package/tables/utils/isTableFreeForAllSlots.js +14 -14
  43. package/tables/utils/isTemporaryTableValid.js +39 -39
  44. package/test/test_counter.js +194 -194
  45. package/test/test_dailyCount.js +81 -81
  46. package/test/test_datesAvailable.js +106 -106
  47. package/test/test_exceptions.js +172 -172
  48. package/test/test_isDateAvailable.js +330 -330
  49. package/test/test_mealTypeCount.js +54 -54
  50. package/test/test_timesAvailable.js +88 -88
  51. package/test-meal-stop-fix.js +147 -147
  52. package/test-meal-stop-simple.js +93 -93
  53. package/test.js +336 -336
  54. package/bundle_entry.js +0 -100
  55. package/moment-timezone-shim.js +0 -179
  56. package/nul +0 -0
@@ -1,115 +1,115 @@
1
- // file: /src/Pages/NewReservation/StepOne/algorithm/maxArrivalsFilter.js
2
-
3
- /**
4
- * Simple max arrivals filter for time slots
5
- *
6
- * Only considers exact arrivals at each time slot without factoring duration
7
- */
8
-
9
- /**
10
- * Get meal type based on time
11
- * @param {string} time - Time string (HH:MM)
12
- * @returns {string|null} - Meal type or null
13
- */
14
- function getMealType(time) {
15
- const hour = parseInt(time.split(':')[0], 10);
16
-
17
- if (hour >= 4 && hour < 11) return 'breakfast';
18
- if (hour >= 11 && hour < 16) return 'lunch';
19
- if (hour >= 16 && hour < 23) return 'dinner';
20
-
21
- return null;
22
- }
23
-
24
- /**
25
- * Extract number value from various data formats
26
- * @param {*} value - Value from data object
27
- * @returns {number|null} - Number or null
28
- */
29
- function extractNumber(value) {
30
- if (!value) return null;
31
-
32
- // Handle MongoDB NumberInt format
33
- if (value.$numberInt) {
34
- return parseInt(value.$numberInt, 10);
35
- }
36
-
37
- // Handle regular number
38
- if (typeof value === 'number') {
39
- return value;
40
- }
41
-
42
- // Handle string number
43
- if (typeof value === 'string') {
44
- const parsed = parseInt(value, 10);
45
- return isNaN(parsed) ? null : parsed;
46
- }
47
-
48
- return null;
49
- }
50
-
51
- /**
52
- * Count guests arriving at exact time
53
- * @param {Array} reservations - Reservation list
54
- * @param {string} date - Date (YYYY-MM-DD)
55
- * @param {string} time - Time (HH:MM)
56
- * @returns {number} - Guest count
57
- */
58
- function countArrivalsAtTime(reservations, date, time) {
59
- return reservations
60
- .filter(r => r.date === date && r.time === time)
61
- .reduce((sum, r) => sum + (parseInt(r.guests, 10) || 0), 0);
62
- }
63
-
64
- /**
65
- * Filter timeblocks based on max arrivals settings
66
- * @param {Object} restaurantData - Restaurant data
67
- * @param {string} date - Date string
68
- * @param {Object} timeblocks - Available timeblocks
69
- * @param {Array} reservations - Existing reservations
70
- * @param {number} guests - New reservation guest count
71
- * @returns {Object} - Filtered timeblocks
72
- */
73
- function filterTimeblocksByMaxArrivals(restaurantData, date, timeblocks, reservations, guests) {
74
- const filteredBlocks = {};
75
-
76
- for (const [time, timeData] of Object.entries(timeblocks)) {
77
- // Get meal type for this time
78
- const mealType = getMealType(time);
79
- if (!mealType) {
80
- // Keep the timeblock if we can't determine its meal type
81
- filteredBlocks[time] = timeData;
82
- continue;
83
- }
84
-
85
- // Get max arrivals config for this meal type
86
- const maxArrivalsConfig = restaurantData[`max-arrivals-${mealType}`];
87
- if (!maxArrivalsConfig) {
88
- // Keep the timeblock if no max arrivals config for this meal type
89
- filteredBlocks[time] = timeData;
90
- continue;
91
- }
92
-
93
- // Get max arrivals value for this specific time
94
- const maxArrivals = extractNumber(maxArrivalsConfig[time]);
95
- if (maxArrivals === null) {
96
- // Keep the timeblock if no specific max arrivals for this time
97
- filteredBlocks[time] = timeData;
98
- continue;
99
- }
100
-
101
- // Count current arrivals at this exact time
102
- const currentArrivals = countArrivalsAtTime(reservations, date, time);
103
-
104
- // Only include timeblock if adding these guests doesn't exceed max arrivals
105
- if (currentArrivals + guests <= maxArrivals) {
106
- filteredBlocks[time] = timeData;
107
- }
108
- }
109
-
110
- return filteredBlocks;
111
- }
112
-
113
- module.exports = {
114
- filterTimeblocksByMaxArrivals
1
+ // file: /src/Pages/NewReservation/StepOne/algorithm/maxArrivalsFilter.js
2
+
3
+ /**
4
+ * Simple max arrivals filter for time slots
5
+ *
6
+ * Only considers exact arrivals at each time slot without factoring duration
7
+ */
8
+
9
+ /**
10
+ * Get meal type based on time
11
+ * @param {string} time - Time string (HH:MM)
12
+ * @returns {string|null} - Meal type or null
13
+ */
14
+ function getMealType(time) {
15
+ const hour = parseInt(time.split(':')[0], 10);
16
+
17
+ if (hour >= 4 && hour < 11) return 'breakfast';
18
+ if (hour >= 11 && hour < 16) return 'lunch';
19
+ if (hour >= 16 && hour < 23) return 'dinner';
20
+
21
+ return null;
22
+ }
23
+
24
+ /**
25
+ * Extract number value from various data formats
26
+ * @param {*} value - Value from data object
27
+ * @returns {number|null} - Number or null
28
+ */
29
+ function extractNumber(value) {
30
+ if (!value) return null;
31
+
32
+ // Handle MongoDB NumberInt format
33
+ if (value.$numberInt) {
34
+ return parseInt(value.$numberInt, 10);
35
+ }
36
+
37
+ // Handle regular number
38
+ if (typeof value === 'number') {
39
+ return value;
40
+ }
41
+
42
+ // Handle string number
43
+ if (typeof value === 'string') {
44
+ const parsed = parseInt(value, 10);
45
+ return isNaN(parsed) ? null : parsed;
46
+ }
47
+
48
+ return null;
49
+ }
50
+
51
+ /**
52
+ * Count guests arriving at exact time
53
+ * @param {Array} reservations - Reservation list
54
+ * @param {string} date - Date (YYYY-MM-DD)
55
+ * @param {string} time - Time (HH:MM)
56
+ * @returns {number} - Guest count
57
+ */
58
+ function countArrivalsAtTime(reservations, date, time) {
59
+ return reservations
60
+ .filter(r => r.date === date && r.time === time)
61
+ .reduce((sum, r) => sum + (parseInt(r.guests, 10) || 0), 0);
62
+ }
63
+
64
+ /**
65
+ * Filter timeblocks based on max arrivals settings
66
+ * @param {Object} restaurantData - Restaurant data
67
+ * @param {string} date - Date string
68
+ * @param {Object} timeblocks - Available timeblocks
69
+ * @param {Array} reservations - Existing reservations
70
+ * @param {number} guests - New reservation guest count
71
+ * @returns {Object} - Filtered timeblocks
72
+ */
73
+ function filterTimeblocksByMaxArrivals(restaurantData, date, timeblocks, reservations, guests) {
74
+ const filteredBlocks = {};
75
+
76
+ for (const [time, timeData] of Object.entries(timeblocks)) {
77
+ // Get meal type for this time
78
+ const mealType = getMealType(time);
79
+ if (!mealType) {
80
+ // Keep the timeblock if we can't determine its meal type
81
+ filteredBlocks[time] = timeData;
82
+ continue;
83
+ }
84
+
85
+ // Get max arrivals config for this meal type
86
+ const maxArrivalsConfig = restaurantData[`max-arrivals-${mealType}`];
87
+ if (!maxArrivalsConfig) {
88
+ // Keep the timeblock if no max arrivals config for this meal type
89
+ filteredBlocks[time] = timeData;
90
+ continue;
91
+ }
92
+
93
+ // Get max arrivals value for this specific time
94
+ const maxArrivals = extractNumber(maxArrivalsConfig[time]);
95
+ if (maxArrivals === null) {
96
+ // Keep the timeblock if no specific max arrivals for this time
97
+ filteredBlocks[time] = timeData;
98
+ continue;
99
+ }
100
+
101
+ // Count current arrivals at this exact time
102
+ const currentArrivals = countArrivalsAtTime(reservations, date, time);
103
+
104
+ // Only include timeblock if adding these guests doesn't exceed max arrivals
105
+ if (currentArrivals + guests <= maxArrivals) {
106
+ filteredBlocks[time] = timeData;
107
+ }
108
+ }
109
+
110
+ return filteredBlocks;
111
+ }
112
+
113
+ module.exports = {
114
+ filterTimeblocksByMaxArrivals
115
115
  };