29 | /**
30 | * Used to check whether the booking is in the past.
31 | * @param {number} year Year of booking.
32 | * @param {number} month Month of booking.
33 | * @param {number} day Day of booking.
34 | * @param {number} hour Hour of booking.
35 | * @param {number} minute Minute of booking.
36 | * @returns {boolean} Returns a boolean representing whether the book is in the past.
37 | */
38 | function isInPast(year, month, day, hour, minute) {
39 | const todayDate = Date.now();
40 | let reqDate = {};
41 | if (hour !== undefined) {
42 | reqDate = Date.UTC(year, month - 1, day, hour, minute);
43 | } else if (day !== undefined) {
44 | reqDate = Date.UTC(year, month - 1, day);
45 | } else {
46 | reqDate = Date.UTC(year, month);
47 | }
48 | return reqDate < todayDate;
49 |
50 | }
51 |
52 | /**
53 | * Used to check whether the booking is at least 24 hours in advance.
54 | * @param {number} year Year of booking.
55 | * @param {number} month Month of booking.
56 | * @param {number} day Day of booking.
57 | * @param {number} hour Hour of booking.
58 | * @param {number} minute Minute of booking.
59 | * @returns {boolean} Returns a boolean representing whether the book is 24 hours in advance.
60 | */
61 | function is24HoursInAdvance(year, month, day, hour, minute) {
62 | const todayDate = new Date(Date.now());
63 | const plus24Hours = todayDate.setUTCHours(todayDate.getUTCHours() + 24);
64 | const reqDate = Date.UTC(year, month-1, day, hour, minute);
65 | return reqDate > plus24Hours;
66 | }
67 |
68 | /**
69 | * Used to check whether the booking is in the bookable time frame (on a weekday between 9 am and 5 pm).
70 | * @param {number} year Year of booking.
71 | * @param {number} month Month of booking.
72 | * @param {number} day Day of booking.
73 | * @param {number} hour Hour of booking.
74 | * @param {number} minute Minute of booking.
75 | * @returns {boolean} Returns a boolean representing whether the booking is in the bookable time frame.
76 | */
77 | function isInBookableTimeframe(year, month, day, hour, minute) {
78 | if (hour !== undefined) {
79 | const reqDate = new Date(Date.UTC(year, month-1, day, hour, minute));
80 | const reqDay = reqDate.getUTCDay();
81 | if (reqDay === 6 || reqDay === 0) return false; // 6 is Saturday, 0 is Sunday.
82 | const reqHour = reqDate.getUTCHours();
83 | if (reqHour < 9 || reqHour > 17) return false;
84 | } else {
85 | const reqDate = new Date(Date.UTC(year, month-1, day));
86 | const reqDay = reqDate.getUTCDay();
87 | if (reqDay === 6 || reqDay === 0) return false; // 6 is Saturday, 0 is Sunday.
88 | }
89 | return true;
90 | }
91 |
92 | /**
93 | * Used to check for missing REST parameters inputs before proceeding with the request.
94 | * @param {number} year Year value to check. Denote with '0' if not checking for this variable.
95 | * @param {number} month Month value to check Denote with '0' if not checking for this variable.
96 | * @param {number} day Day value to check Denote with '0' if not checking for this variable.
97 | * @param {number} hour Hour value to check. Denote with '0' if not checking for this variable.
98 | * @param {number} minute Minute value to check. Denote with '0' if not checking for this variable.
99 | * @returns {object} Returns an object with info on what parameter was missing.
100 | */
101 | function checkMissingInputs(year, month, day, hour, minute) {
102 | if (!year) return {success: false, message: 'Request is missing parameter: year'};
103 | if (!month) return {success: false, message: 'Request is missing parameter: month'};
104 | if (!day) return {success: false, message: 'Request is missing parameter: day'};
105 | if (!hour) return {success: false, message: 'Request is missing parameter: hour'};
106 | if (!minute) return {success: false, message: 'Request is missing parameter: minute'};
107 | }
108 |
109 | /**
110 | * Used to validate bookings.
111 | * @param {number} year Year of booking to check.
112 | * @param {number} month Month of booking to check.
113 | * @param {number} day Day of booking to check.
114 | * @param {number} hour Hour of booking to check.
115 | * @param {number} minute Minute of booking to check.
116 | * @returns {object} Returns an object with info on why the booking was invalid.
117 | */
118 | function validateBooking(year, month, day, hour, minute) {
119 | const missingInputs = checkMissingInputs(year, month, day, hour, minute);
120 | if (missingInputs) return missingInputs;
121 | if (isInPast(year, month, day, hour, minute))
122 | return {success: false, message: 'Cannot book time in the past'};
123 | if (!isInBookableTimeframe(year, month, day, hour, minute))
124 | return {success: false, message: 'Cannot book outside bookable timeframe'};
125 | if (!is24HoursInAdvance(year, month, day, hour, minute))
126 | return {success: false, message: 'Cannot book with less than 24 hours in advance'};
127 | }
128 |
129 | /**
130 | * Used to validate GET Timeslot requests.
131 | * @param {number} year Year parameter to check.
132 | * @param {number} month Month parameter to check.
133 | * @param {number} day Day parameter to check.
134 | * @returns {object} Returns an object with info on why the request was invalid.
135 | */
136 | function validateGetTimeslots(year, month, day) {
137 | const missingInputs = checkMissingInputs(year, month, day, '0', '0');
138 | if (missingInputs) return missingInputs;
139 | if (isInPast(year, month, day, undefined, undefined))
140 | return {success: false, message: 'No timeslots are available in the past'};
141 | if (!isInBookableTimeframe(year, month, day, undefined, undefined))
142 | return {success: false, message: 'No timeslots exist outside bookable timeframe'};
143 | }
144 |
145 | /**
146 | * Used to validate GET Days requests.
147 | * @param {number} year Year parameter to check.
148 | * @param {number} month Month parameter to check.
149 | * @returns {object} Returns an object with info on why the request was invalid.
150 | */
151 | function validateGetDays(year, month) {
152 | const missingInputs = checkMissingInputs(year, month, '0', '0', '0');
153 | if (missingInputs) return missingInputs;
154 | if (isInPast(year, month, undefined, undefined, undefined))
155 | return {success: false, message: 'No timeslots are available in the past'};
156 | }
157 |
158 | module.exports = {
159 | checkMissingInputs,
160 | validateBooking,
161 | validateGetTimeslots,
162 | validateGetDays
163 | };
164 |
165 |