goldstars-services 1.0.69 → 1.0.71
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.js +21 -0
- package/dist/models/reservation.model.js +2 -1
- package/dist/models/scheduleException.model.js +87 -0
- package/dist/models/user.model.js +32 -0
- package/dist/models/weeklyScheduleTemplate.model.js +73 -0
- package/dist/scripts/migrateInitialSchedules.js +331 -0
- package/dist/services/reservation.service.js +135 -42
- package/dist/services/scheduleException.service.js +288 -0
- package/dist/services/userSuspension.service.js +253 -0
- package/dist/services/weeklyScheduleTemplate.service.js +226 -0
- package/package.json +1 -1
|
@@ -7,6 +7,9 @@ exports.default = void 0;
|
|
|
7
7
|
var _reservationModel = _interopRequireDefault(require("../models/reservation.model.js"));
|
|
8
8
|
var _bikeModel = _interopRequireDefault(require("../models/bike.model.js"));
|
|
9
9
|
var _instructorScheduleService = _interopRequireDefault(require("./instructorSchedule.service.js"));
|
|
10
|
+
var _userSuspensionService = _interopRequireDefault(require("./userSuspension.service.js"));
|
|
11
|
+
var _weeklyScheduleTemplateService = _interopRequireDefault(require("./weeklyScheduleTemplate.service.js"));
|
|
12
|
+
var _scheduleExceptionService = _interopRequireDefault(require("./scheduleException.service.js"));
|
|
10
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
14
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
15
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -16,6 +19,80 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
16
19
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
17
20
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } // MicroService/src/services/reservation.service.js
|
|
18
21
|
// Needed to check bike status/location
|
|
22
|
+
/**
|
|
23
|
+
* Extrae el time slot string (ej: '7am', '5pm') de un timestamp
|
|
24
|
+
* @param {Date} timestamp - Timestamp UTC
|
|
25
|
+
* @returns {string} - Time slot string (ej: '7am', '8:30am')
|
|
26
|
+
*/
|
|
27
|
+
var extractTimeSlotFromTimestamp = timestamp => {
|
|
28
|
+
var hours = timestamp.getHours();
|
|
29
|
+
var minutes = timestamp.getMinutes();
|
|
30
|
+
var period = hours >= 12 ? 'pm' : 'am';
|
|
31
|
+
if (hours > 12) hours -= 12;
|
|
32
|
+
if (hours === 0) hours = 12;
|
|
33
|
+
if (minutes === 0) {
|
|
34
|
+
return "".concat(hours).concat(period);
|
|
35
|
+
} else {
|
|
36
|
+
return "".concat(hours, ":").concat(minutes.toString().padStart(2, '0')).concat(period);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Verifica si un time slot está disponible para reservas basándose en templates y excepciones
|
|
42
|
+
* @param {string} location - Ubicación
|
|
43
|
+
* @param {Date} timestamp - Timestamp de la reserva (UTC)
|
|
44
|
+
* @returns {Promise<boolean>} - True si está disponible, false si no
|
|
45
|
+
*/
|
|
46
|
+
var isTimeSlotAvailableForReservation = /*#__PURE__*/function () {
|
|
47
|
+
var _ref = _asyncToGenerator(function* (location, timestamp) {
|
|
48
|
+
try {
|
|
49
|
+
var dayOfWeek = timestamp.getDay();
|
|
50
|
+
|
|
51
|
+
// Fines de semana no disponibles
|
|
52
|
+
if (dayOfWeek === 0 || dayOfWeek === 6) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
var timeSlot = extractTimeSlotFromTimestamp(timestamp);
|
|
56
|
+
|
|
57
|
+
// 1. Verificar excepciones (tienen prioridad)
|
|
58
|
+
var exceptions = yield _scheduleExceptionService.default.getExceptionsForDate(location, timestamp);
|
|
59
|
+
if (exceptions.length > 0) {
|
|
60
|
+
for (var exc of exceptions) {
|
|
61
|
+
// Si está cerrado, no disponible
|
|
62
|
+
if (exc.exceptionType === 'CLOSED') {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Si el slot específico está bloqueado
|
|
67
|
+
if (exc.exceptionType === 'SLOT_BLOCKED' && exc.blockedTimeSlot === timeSlot) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Si hay horarios custom, usar esos
|
|
72
|
+
if (exc.exceptionType === 'CUSTOM_HOURS') {
|
|
73
|
+
return exc.customTimeSlots.some(s => s.time === timeSlot && s.isActive);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 2. Si no hay excepciones, usar template semanal
|
|
79
|
+
var weeklySchedule = yield _weeklyScheduleTemplateService.default.getWeeklyScheduleForDay(location, dayOfWeek);
|
|
80
|
+
if (!weeklySchedule) {
|
|
81
|
+
return false; // No hay horarios configurados para este día
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Verificar si el time slot está en el template y está activo
|
|
85
|
+
return weeklySchedule.timeSlots.some(s => s.time === timeSlot && s.isActive);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('Error verificando disponibilidad de horario:', error);
|
|
88
|
+
return false; // En caso de error, no permitir la reserva
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return function isTimeSlotAvailableForReservation(_x, _x2) {
|
|
92
|
+
return _ref.apply(this, arguments);
|
|
93
|
+
};
|
|
94
|
+
}();
|
|
95
|
+
|
|
19
96
|
/**
|
|
20
97
|
* Checks if a bike is already reserved for a specific timestamp.
|
|
21
98
|
* @param {string} bikeId - The ID of the bike.
|
|
@@ -23,7 +100,7 @@ function _asyncToGenerator(n) { return function () { var t = this, e = arguments
|
|
|
23
100
|
* @returns {Promise<boolean>} - True if the bike is already reserved, false otherwise.
|
|
24
101
|
*/
|
|
25
102
|
var isBikeReserved = /*#__PURE__*/function () {
|
|
26
|
-
var
|
|
103
|
+
var _ref2 = _asyncToGenerator(function* (bikeId, timestamp) {
|
|
27
104
|
var searchTimestamp = new Date(timestamp);
|
|
28
105
|
if (isNaN(searchTimestamp.getTime())) {
|
|
29
106
|
throw new Error('Timestamp inválido proporcionado a isBikeReserved.');
|
|
@@ -36,8 +113,8 @@ var isBikeReserved = /*#__PURE__*/function () {
|
|
|
36
113
|
});
|
|
37
114
|
return !!existingReservation;
|
|
38
115
|
});
|
|
39
|
-
return function isBikeReserved(
|
|
40
|
-
return
|
|
116
|
+
return function isBikeReserved(_x3, _x4) {
|
|
117
|
+
return _ref2.apply(this, arguments);
|
|
41
118
|
};
|
|
42
119
|
}();
|
|
43
120
|
|
|
@@ -52,7 +129,7 @@ var isBikeReserved = /*#__PURE__*/function () {
|
|
|
52
129
|
* @throws {Error} - If bike not found, is instructor bike, timestamp invalid, or already reserved.
|
|
53
130
|
*/
|
|
54
131
|
var createReservation = /*#__PURE__*/function () {
|
|
55
|
-
var
|
|
132
|
+
var _ref3 = _asyncToGenerator(function* (reservationData) {
|
|
56
133
|
var {
|
|
57
134
|
userId,
|
|
58
135
|
bikeId,
|
|
@@ -66,28 +143,41 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
66
143
|
|
|
67
144
|
// --- BEGIN NEW VALIDATIONS ---
|
|
68
145
|
|
|
69
|
-
// 1.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
146
|
+
// 1. Validaciones por usuario solo aplican cuando hay usuario asociado
|
|
147
|
+
if (userId) {
|
|
148
|
+
// 1.a Verificar suspensión de usuario
|
|
149
|
+
var suspensionCheck = yield _userSuspensionService.default.checkUserSuspension(userId, 'bikes');
|
|
150
|
+
if (suspensionCheck.isSuspended) {
|
|
151
|
+
var untilMessage = suspensionCheck.suspendedUntil ? " hasta ".concat(new Date(suspensionCheck.suspendedUntil).toLocaleDateString('es-VE')) : ' indefinidamente';
|
|
152
|
+
throw new Error("Tu cuenta est\xE1 suspendida".concat(untilMessage, ". Raz\xF3n: ").concat(suspensionCheck.reason));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 1.b Check if user already has a reservation for this EXACT timestamp
|
|
156
|
+
var existingReservationSameSlot = yield _reservationModel.default.findOne({
|
|
157
|
+
userId,
|
|
158
|
+
timestamp: reservationTimestamp
|
|
159
|
+
});
|
|
160
|
+
if (existingReservationSameSlot) {
|
|
161
|
+
throw new Error('Ya tienes una reserva agendada para esta fecha y hora.');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 1.c Check if user already has an UPCOMING reservation
|
|
165
|
+
var now = new Date();
|
|
166
|
+
var existingUpcomingReservation = yield _reservationModel.default.findOne({
|
|
167
|
+
userId,
|
|
168
|
+
timestamp: {
|
|
169
|
+
$gte: now
|
|
170
|
+
} // Find reservations where the timestamp is now or in the future
|
|
171
|
+
});
|
|
172
|
+
if (existingUpcomingReservation) {
|
|
173
|
+
throw new Error('Ya tienes una reserva activa. Debes esperar a que pase para agendar otra.');
|
|
174
|
+
}
|
|
76
175
|
}
|
|
77
176
|
|
|
78
|
-
// 2.
|
|
79
|
-
var
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
timestamp: {
|
|
83
|
-
$gte: now
|
|
84
|
-
} // Find reservations where the timestamp is now or in the future
|
|
85
|
-
});
|
|
86
|
-
if (existingUpcomingReservation) {
|
|
87
|
-
// Optional: Provide more details about the existing reservation if needed
|
|
88
|
-
// const existingTime = existingUpcomingReservation.timestamp.toLocaleString('es-VE');
|
|
89
|
-
// throw new Error(`Ya tienes una reserva activa para ${existingTime}. Debes esperar a que pase para agendar otra.`);
|
|
90
|
-
throw new Error('Ya tienes una reserva activa. Debes esperar a que pase para agendar otra.');
|
|
177
|
+
// 2. Verificar disponibilidad de horario (templates y excepciones)
|
|
178
|
+
var isSlotAvailable = yield isTimeSlotAvailableForReservation(location, reservationTimestamp);
|
|
179
|
+
if (!isSlotAvailable) {
|
|
180
|
+
throw new Error('Este horario no está disponible para reservas en esta ubicación.');
|
|
91
181
|
}
|
|
92
182
|
|
|
93
183
|
// --- END NEW VALIDATIONS ---
|
|
@@ -121,8 +211,8 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
121
211
|
yield newReservation.save();
|
|
122
212
|
return newReservation;
|
|
123
213
|
});
|
|
124
|
-
return function createReservation(
|
|
125
|
-
return
|
|
214
|
+
return function createReservation(_x5) {
|
|
215
|
+
return _ref3.apply(this, arguments);
|
|
126
216
|
};
|
|
127
217
|
}();
|
|
128
218
|
|
|
@@ -134,7 +224,7 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
134
224
|
* @returns {Promise<Array<object>>} - An array of bike objects, each with an added 'reservationStatus' field.
|
|
135
225
|
*/
|
|
136
226
|
var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
137
|
-
var
|
|
227
|
+
var _ref4 = _asyncToGenerator(function* (location, timestamp) {
|
|
138
228
|
var includeInstructor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
139
229
|
var checkTimestamp = new Date(timestamp);
|
|
140
230
|
if (isNaN(checkTimestamp.getTime())) {
|
|
@@ -221,8 +311,8 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
|
221
311
|
});
|
|
222
312
|
return bikesWithStatus;
|
|
223
313
|
});
|
|
224
|
-
return function getBikeAvailabilityForSlot(
|
|
225
|
-
return
|
|
314
|
+
return function getBikeAvailabilityForSlot(_x6, _x7) {
|
|
315
|
+
return _ref4.apply(this, arguments);
|
|
226
316
|
};
|
|
227
317
|
}();
|
|
228
318
|
|
|
@@ -241,7 +331,7 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
|
241
331
|
* @throws {Error} - If reservation not found or user is not authorized.
|
|
242
332
|
*/
|
|
243
333
|
var cancelReservation = /*#__PURE__*/function () {
|
|
244
|
-
var
|
|
334
|
+
var _ref5 = _asyncToGenerator(function* (reservationId, userId, userRole) {
|
|
245
335
|
var reservation = yield _reservationModel.default.findById(reservationId);
|
|
246
336
|
if (!reservation) {
|
|
247
337
|
throw new Error('Reserva no encontrada.');
|
|
@@ -261,8 +351,8 @@ var cancelReservation = /*#__PURE__*/function () {
|
|
|
261
351
|
message: 'Reserva cancelada exitosamente.'
|
|
262
352
|
};
|
|
263
353
|
});
|
|
264
|
-
return function cancelReservation(
|
|
265
|
-
return
|
|
354
|
+
return function cancelReservation(_x8, _x9, _x10) {
|
|
355
|
+
return _ref5.apply(this, arguments);
|
|
266
356
|
};
|
|
267
357
|
}();
|
|
268
358
|
|
|
@@ -272,12 +362,12 @@ var cancelReservation = /*#__PURE__*/function () {
|
|
|
272
362
|
* @returns {Promise<object|null>} - El documento de la reservación o null si no existe.
|
|
273
363
|
*/
|
|
274
364
|
var getReservationById = /*#__PURE__*/function () {
|
|
275
|
-
var
|
|
365
|
+
var _ref6 = _asyncToGenerator(function* (reservationId) {
|
|
276
366
|
var reservation = yield _reservationModel.default.findById(reservationId).populate('bikeId', 'name location').populate('userId', 'firstName lastName email');
|
|
277
367
|
return reservation;
|
|
278
368
|
});
|
|
279
|
-
return function getReservationById(
|
|
280
|
-
return
|
|
369
|
+
return function getReservationById(_x11) {
|
|
370
|
+
return _ref6.apply(this, arguments);
|
|
281
371
|
};
|
|
282
372
|
}();
|
|
283
373
|
|
|
@@ -288,7 +378,7 @@ var getReservationById = /*#__PURE__*/function () {
|
|
|
288
378
|
* @throws {Error} - Si la reserva no se encuentra o no se puede cancelar.
|
|
289
379
|
*/
|
|
290
380
|
var cancelReservationById = /*#__PURE__*/function () {
|
|
291
|
-
var
|
|
381
|
+
var _ref7 = _asyncToGenerator(function* (reservationId) {
|
|
292
382
|
var reservation = yield _reservationModel.default.findById(reservationId);
|
|
293
383
|
if (!reservation) {
|
|
294
384
|
throw new Error('Reserva no encontrada.');
|
|
@@ -304,8 +394,8 @@ var cancelReservationById = /*#__PURE__*/function () {
|
|
|
304
394
|
deletedReservation: reservation
|
|
305
395
|
};
|
|
306
396
|
});
|
|
307
|
-
return function cancelReservationById(
|
|
308
|
-
return
|
|
397
|
+
return function cancelReservationById(_x12) {
|
|
398
|
+
return _ref7.apply(this, arguments);
|
|
309
399
|
};
|
|
310
400
|
}();
|
|
311
401
|
|
|
@@ -316,7 +406,7 @@ var cancelReservationById = /*#__PURE__*/function () {
|
|
|
316
406
|
* @throws {Error} - Si no se proporciona el ID de usuario.
|
|
317
407
|
*/
|
|
318
408
|
var getReservationsByUserId = /*#__PURE__*/function () {
|
|
319
|
-
var
|
|
409
|
+
var _ref8 = _asyncToGenerator(function* (userId) {
|
|
320
410
|
if (!userId) {
|
|
321
411
|
throw new Error('El ID de usuario es requerido para obtener las reservaciones.');
|
|
322
412
|
}
|
|
@@ -329,8 +419,8 @@ var getReservationsByUserId = /*#__PURE__*/function () {
|
|
|
329
419
|
|
|
330
420
|
return reservations;
|
|
331
421
|
});
|
|
332
|
-
return function getReservationsByUserId(
|
|
333
|
-
return
|
|
422
|
+
return function getReservationsByUserId(_x13) {
|
|
423
|
+
return _ref8.apply(this, arguments);
|
|
334
424
|
};
|
|
335
425
|
}();
|
|
336
426
|
var _default = exports.default = {
|
|
@@ -341,5 +431,8 @@ var _default = exports.default = {
|
|
|
341
431
|
cancelReservationById,
|
|
342
432
|
isBikeReserved,
|
|
343
433
|
// Keep exporting isBikeReserved if used elsewhere, otherwise could be removed if only internal
|
|
344
|
-
getReservationsByUserId
|
|
434
|
+
getReservationsByUserId,
|
|
435
|
+
isTimeSlotAvailableForReservation,
|
|
436
|
+
// Export for potential use in API layer
|
|
437
|
+
extractTimeSlotFromTimestamp // Export for potential use in API layer
|
|
345
438
|
};
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateScheduleException = exports.toggleExceptionStatus = exports.getExceptionsForDateRange = exports.getExceptionsForDate = exports.getAllScheduleExceptions = exports.deleteScheduleException = exports.default = exports.createScheduleException = void 0;
|
|
7
|
+
var _scheduleExceptionModel = _interopRequireDefault(require("../models/scheduleException.model.js"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
12
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
13
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
15
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
16
|
+
/**
|
|
17
|
+
* Crear una excepción de horario
|
|
18
|
+
* @param {Object} exceptionData - Datos de la excepción
|
|
19
|
+
* @returns {Object} Excepción creada
|
|
20
|
+
*/
|
|
21
|
+
var createScheduleException = exports.createScheduleException = /*#__PURE__*/function () {
|
|
22
|
+
var _ref = _asyncToGenerator(function* (exceptionData) {
|
|
23
|
+
try {
|
|
24
|
+
var {
|
|
25
|
+
location,
|
|
26
|
+
exceptionDate,
|
|
27
|
+
exceptionType,
|
|
28
|
+
customTimeSlots,
|
|
29
|
+
blockedTimeSlot,
|
|
30
|
+
reason,
|
|
31
|
+
createdBy
|
|
32
|
+
} = exceptionData;
|
|
33
|
+
|
|
34
|
+
// Validar ubicación
|
|
35
|
+
var validLocations = ['C.C Las Virtudes', 'Sambil Paraguaná'];
|
|
36
|
+
if (!validLocations.includes(location)) {
|
|
37
|
+
throw new Error("Ubicaci\xF3n inv\xE1lida. Debe ser: ".concat(validLocations.join(' o ')));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Validar tipo de excepción
|
|
41
|
+
var validTypes = ['CLOSED', 'CUSTOM_HOURS', 'SLOT_BLOCKED'];
|
|
42
|
+
if (!validTypes.includes(exceptionType)) {
|
|
43
|
+
throw new Error("Tipo de excepci\xF3n inv\xE1lido. Debe ser: ".concat(validTypes.join(', ')));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Validaciones específicas por tipo
|
|
47
|
+
if (exceptionType === 'CUSTOM_HOURS' && (!customTimeSlots || customTimeSlots.length === 0)) {
|
|
48
|
+
throw new Error('CUSTOM_HOURS requiere customTimeSlots');
|
|
49
|
+
}
|
|
50
|
+
if (exceptionType === 'SLOT_BLOCKED' && !blockedTimeSlot) {
|
|
51
|
+
throw new Error('SLOT_BLOCKED requiere blockedTimeSlot');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Validar formato de timeSlots si existen
|
|
55
|
+
var timeRegex = /^(1[0-2]|[1-9])(:([0-5][0-9]))?(am|pm)$/i;
|
|
56
|
+
if (customTimeSlots && customTimeSlots.length > 0) {
|
|
57
|
+
for (var slot of customTimeSlots) {
|
|
58
|
+
if (!timeRegex.test(slot.time)) {
|
|
59
|
+
throw new Error("Formato de hora inv\xE1lido: ".concat(slot.time));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (blockedTimeSlot && !timeRegex.test(blockedTimeSlot)) {
|
|
64
|
+
throw new Error("Formato de hora inv\xE1lido: ".concat(blockedTimeSlot));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Normalizar fecha a medianoche UTC
|
|
68
|
+
var normalizedDate = new Date(exceptionDate);
|
|
69
|
+
normalizedDate.setHours(0, 0, 0, 0);
|
|
70
|
+
var exception = new _scheduleExceptionModel.default({
|
|
71
|
+
location,
|
|
72
|
+
exceptionDate: normalizedDate,
|
|
73
|
+
exceptionType,
|
|
74
|
+
customTimeSlots: customTimeSlots || [],
|
|
75
|
+
blockedTimeSlot: blockedTimeSlot || null,
|
|
76
|
+
reason: reason || '',
|
|
77
|
+
isActive: true,
|
|
78
|
+
createdBy
|
|
79
|
+
});
|
|
80
|
+
yield exception.save();
|
|
81
|
+
return exception;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw new Error("Error al crear excepci\xF3n: ".concat(error.message));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return function createScheduleException(_x) {
|
|
87
|
+
return _ref.apply(this, arguments);
|
|
88
|
+
};
|
|
89
|
+
}();
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Obtener excepciones para una fecha específica
|
|
93
|
+
* @param {String} location - Ubicación
|
|
94
|
+
* @param {Date} date - Fecha a consultar
|
|
95
|
+
* @returns {Array} Excepciones activas para esa fecha
|
|
96
|
+
*/
|
|
97
|
+
var getExceptionsForDate = exports.getExceptionsForDate = /*#__PURE__*/function () {
|
|
98
|
+
var _ref2 = _asyncToGenerator(function* (location, date) {
|
|
99
|
+
try {
|
|
100
|
+
// Normalizar fecha a medianoche
|
|
101
|
+
var normalizedDate = new Date(date);
|
|
102
|
+
normalizedDate.setHours(0, 0, 0, 0);
|
|
103
|
+
var endOfDay = new Date(normalizedDate);
|
|
104
|
+
endOfDay.setHours(23, 59, 59, 999);
|
|
105
|
+
var exceptions = yield _scheduleExceptionModel.default.find({
|
|
106
|
+
location,
|
|
107
|
+
exceptionDate: {
|
|
108
|
+
$gte: normalizedDate,
|
|
109
|
+
$lte: endOfDay
|
|
110
|
+
},
|
|
111
|
+
isActive: true
|
|
112
|
+
}).populate('createdBy', 'firstName lastName email');
|
|
113
|
+
return exceptions;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
throw new Error("Error al obtener excepciones para fecha: ".concat(error.message));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return function getExceptionsForDate(_x2, _x3) {
|
|
119
|
+
return _ref2.apply(this, arguments);
|
|
120
|
+
};
|
|
121
|
+
}();
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Obtener excepciones para un rango de fechas
|
|
125
|
+
* @param {String} location - Ubicación
|
|
126
|
+
* @param {Date} startDate - Fecha inicial
|
|
127
|
+
* @param {Date} endDate - Fecha final
|
|
128
|
+
* @returns {Array} Excepciones en el rango
|
|
129
|
+
*/
|
|
130
|
+
var getExceptionsForDateRange = exports.getExceptionsForDateRange = /*#__PURE__*/function () {
|
|
131
|
+
var _ref3 = _asyncToGenerator(function* (location, startDate, endDate) {
|
|
132
|
+
try {
|
|
133
|
+
// Normalizar fechas
|
|
134
|
+
var normalizedStart = new Date(startDate);
|
|
135
|
+
normalizedStart.setHours(0, 0, 0, 0);
|
|
136
|
+
var normalizedEnd = new Date(endDate);
|
|
137
|
+
normalizedEnd.setHours(23, 59, 59, 999);
|
|
138
|
+
var exceptions = yield _scheduleExceptionModel.default.find({
|
|
139
|
+
location,
|
|
140
|
+
exceptionDate: {
|
|
141
|
+
$gte: normalizedStart,
|
|
142
|
+
$lte: normalizedEnd
|
|
143
|
+
},
|
|
144
|
+
isActive: true
|
|
145
|
+
}).populate('createdBy', 'firstName lastName email').sort({
|
|
146
|
+
exceptionDate: 1
|
|
147
|
+
});
|
|
148
|
+
return exceptions;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
throw new Error("Error al obtener excepciones para rango: ".concat(error.message));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return function getExceptionsForDateRange(_x4, _x5, _x6) {
|
|
154
|
+
return _ref3.apply(this, arguments);
|
|
155
|
+
};
|
|
156
|
+
}();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Eliminar una excepción
|
|
160
|
+
* @param {String} exceptionId - ID de la excepción
|
|
161
|
+
* @returns {Object} Excepción eliminada
|
|
162
|
+
*/
|
|
163
|
+
var deleteScheduleException = exports.deleteScheduleException = /*#__PURE__*/function () {
|
|
164
|
+
var _ref4 = _asyncToGenerator(function* (exceptionId) {
|
|
165
|
+
try {
|
|
166
|
+
var exception = yield _scheduleExceptionModel.default.findByIdAndDelete(exceptionId);
|
|
167
|
+
if (!exception) {
|
|
168
|
+
throw new Error('Excepción no encontrada');
|
|
169
|
+
}
|
|
170
|
+
return exception;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
throw new Error("Error al eliminar excepci\xF3n: ".concat(error.message));
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return function deleteScheduleException(_x7) {
|
|
176
|
+
return _ref4.apply(this, arguments);
|
|
177
|
+
};
|
|
178
|
+
}();
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Actualizar una excepción
|
|
182
|
+
* @param {String} exceptionId - ID de la excepción
|
|
183
|
+
* @param {Object} updateData - Datos a actualizar
|
|
184
|
+
* @returns {Object} Excepción actualizada
|
|
185
|
+
*/
|
|
186
|
+
var updateScheduleException = exports.updateScheduleException = /*#__PURE__*/function () {
|
|
187
|
+
var _ref5 = _asyncToGenerator(function* (exceptionId, updateData) {
|
|
188
|
+
try {
|
|
189
|
+
// Validar formato de timeSlots si se están actualizando
|
|
190
|
+
var timeRegex = /^(1[0-2]|[1-9])(:([0-5][0-9]))?(am|pm)$/i;
|
|
191
|
+
if (updateData.customTimeSlots && updateData.customTimeSlots.length > 0) {
|
|
192
|
+
for (var slot of updateData.customTimeSlots) {
|
|
193
|
+
if (!timeRegex.test(slot.time)) {
|
|
194
|
+
throw new Error("Formato de hora inv\xE1lido: ".concat(slot.time));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (updateData.blockedTimeSlot && !timeRegex.test(updateData.blockedTimeSlot)) {
|
|
199
|
+
throw new Error("Formato de hora inv\xE1lido: ".concat(updateData.blockedTimeSlot));
|
|
200
|
+
}
|
|
201
|
+
var exception = yield _scheduleExceptionModel.default.findByIdAndUpdate(exceptionId, _objectSpread(_objectSpread({}, updateData), {}, {
|
|
202
|
+
updatedAt: new Date()
|
|
203
|
+
}), {
|
|
204
|
+
new: true,
|
|
205
|
+
runValidators: true
|
|
206
|
+
}).populate('createdBy', 'firstName lastName email');
|
|
207
|
+
if (!exception) {
|
|
208
|
+
throw new Error('Excepción no encontrada');
|
|
209
|
+
}
|
|
210
|
+
return exception;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
throw new Error("Error al actualizar excepci\xF3n: ".concat(error.message));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return function updateScheduleException(_x8, _x9) {
|
|
216
|
+
return _ref5.apply(this, arguments);
|
|
217
|
+
};
|
|
218
|
+
}();
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Obtener todas las excepciones con filtros opcionales
|
|
222
|
+
* @param {Object} filters - Filtros (location, isActive, etc.)
|
|
223
|
+
* @returns {Array} Excepciones
|
|
224
|
+
*/
|
|
225
|
+
var getAllScheduleExceptions = exports.getAllScheduleExceptions = /*#__PURE__*/function () {
|
|
226
|
+
var _ref6 = _asyncToGenerator(function* () {
|
|
227
|
+
var filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
228
|
+
try {
|
|
229
|
+
var query = {};
|
|
230
|
+
if (filters.location) {
|
|
231
|
+
query.location = filters.location;
|
|
232
|
+
}
|
|
233
|
+
if (filters.isActive !== undefined) {
|
|
234
|
+
query.isActive = filters.isActive;
|
|
235
|
+
}
|
|
236
|
+
if (filters.exceptionType) {
|
|
237
|
+
query.exceptionType = filters.exceptionType;
|
|
238
|
+
}
|
|
239
|
+
var exceptions = yield _scheduleExceptionModel.default.find(query).populate('createdBy', 'firstName lastName email').sort({
|
|
240
|
+
exceptionDate: -1
|
|
241
|
+
});
|
|
242
|
+
return exceptions;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
throw new Error("Error al obtener excepciones: ".concat(error.message));
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
return function getAllScheduleExceptions() {
|
|
248
|
+
return _ref6.apply(this, arguments);
|
|
249
|
+
};
|
|
250
|
+
}();
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Activar/desactivar una excepción
|
|
254
|
+
* @param {String} exceptionId - ID de la excepción
|
|
255
|
+
* @param {Boolean} isActive - Estado
|
|
256
|
+
* @returns {Object} Excepción actualizada
|
|
257
|
+
*/
|
|
258
|
+
var toggleExceptionStatus = exports.toggleExceptionStatus = /*#__PURE__*/function () {
|
|
259
|
+
var _ref7 = _asyncToGenerator(function* (exceptionId, isActive) {
|
|
260
|
+
try {
|
|
261
|
+
var exception = yield _scheduleExceptionModel.default.findByIdAndUpdate(exceptionId, {
|
|
262
|
+
isActive,
|
|
263
|
+
updatedAt: new Date()
|
|
264
|
+
}, {
|
|
265
|
+
new: true,
|
|
266
|
+
runValidators: true
|
|
267
|
+
}).populate('createdBy', 'firstName lastName email');
|
|
268
|
+
if (!exception) {
|
|
269
|
+
throw new Error('Excepción no encontrada');
|
|
270
|
+
}
|
|
271
|
+
return exception;
|
|
272
|
+
} catch (error) {
|
|
273
|
+
throw new Error("Error al cambiar estado de excepci\xF3n: ".concat(error.message));
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return function toggleExceptionStatus(_x10, _x11) {
|
|
277
|
+
return _ref7.apply(this, arguments);
|
|
278
|
+
};
|
|
279
|
+
}();
|
|
280
|
+
var _default = exports.default = {
|
|
281
|
+
createScheduleException,
|
|
282
|
+
getExceptionsForDate,
|
|
283
|
+
getExceptionsForDateRange,
|
|
284
|
+
deleteScheduleException,
|
|
285
|
+
updateScheduleException,
|
|
286
|
+
getAllScheduleExceptions,
|
|
287
|
+
toggleExceptionStatus
|
|
288
|
+
};
|