goldstars-services 1.0.70 → 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.
@@ -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 _ref = _asyncToGenerator(function* (bikeId, timestamp) {
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(_x, _x2) {
40
- return _ref.apply(this, arguments);
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 _ref2 = _asyncToGenerator(function* (reservationData) {
132
+ var _ref3 = _asyncToGenerator(function* (reservationData) {
56
133
  var {
57
134
  userId,
58
135
  bikeId,
@@ -68,7 +145,14 @@ var createReservation = /*#__PURE__*/function () {
68
145
 
69
146
  // 1. Validaciones por usuario solo aplican cuando hay usuario asociado
70
147
  if (userId) {
71
- // 1.a Check if user already has a reservation for this EXACT timestamp
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
72
156
  var existingReservationSameSlot = yield _reservationModel.default.findOne({
73
157
  userId,
74
158
  timestamp: reservationTimestamp
@@ -77,7 +161,7 @@ var createReservation = /*#__PURE__*/function () {
77
161
  throw new Error('Ya tienes una reserva agendada para esta fecha y hora.');
78
162
  }
79
163
 
80
- // 1.b Check if user already has an UPCOMING reservation
164
+ // 1.c Check if user already has an UPCOMING reservation
81
165
  var now = new Date();
82
166
  var existingUpcomingReservation = yield _reservationModel.default.findOne({
83
167
  userId,
@@ -86,13 +170,16 @@ var createReservation = /*#__PURE__*/function () {
86
170
  } // Find reservations where the timestamp is now or in the future
87
171
  });
88
172
  if (existingUpcomingReservation) {
89
- // Optional: Provide more details about the existing reservation if needed
90
- // const existingTime = existingUpcomingReservation.timestamp.toLocaleString('es-VE');
91
- // throw new Error(`Ya tienes una reserva activa para ${existingTime}. Debes esperar a que pase para agendar otra.`);
92
173
  throw new Error('Ya tienes una reserva activa. Debes esperar a que pase para agendar otra.');
93
174
  }
94
175
  }
95
176
 
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.');
181
+ }
182
+
96
183
  // --- END NEW VALIDATIONS ---
97
184
 
98
185
  // 1. Validate Bike
@@ -124,8 +211,8 @@ var createReservation = /*#__PURE__*/function () {
124
211
  yield newReservation.save();
125
212
  return newReservation;
126
213
  });
127
- return function createReservation(_x3) {
128
- return _ref2.apply(this, arguments);
214
+ return function createReservation(_x5) {
215
+ return _ref3.apply(this, arguments);
129
216
  };
130
217
  }();
131
218
 
@@ -137,7 +224,7 @@ var createReservation = /*#__PURE__*/function () {
137
224
  * @returns {Promise<Array<object>>} - An array of bike objects, each with an added 'reservationStatus' field.
138
225
  */
139
226
  var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
140
- var _ref3 = _asyncToGenerator(function* (location, timestamp) {
227
+ var _ref4 = _asyncToGenerator(function* (location, timestamp) {
141
228
  var includeInstructor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
142
229
  var checkTimestamp = new Date(timestamp);
143
230
  if (isNaN(checkTimestamp.getTime())) {
@@ -224,8 +311,8 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
224
311
  });
225
312
  return bikesWithStatus;
226
313
  });
227
- return function getBikeAvailabilityForSlot(_x4, _x5) {
228
- return _ref3.apply(this, arguments);
314
+ return function getBikeAvailabilityForSlot(_x6, _x7) {
315
+ return _ref4.apply(this, arguments);
229
316
  };
230
317
  }();
231
318
 
@@ -244,7 +331,7 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
244
331
  * @throws {Error} - If reservation not found or user is not authorized.
245
332
  */
246
333
  var cancelReservation = /*#__PURE__*/function () {
247
- var _ref4 = _asyncToGenerator(function* (reservationId, userId, userRole) {
334
+ var _ref5 = _asyncToGenerator(function* (reservationId, userId, userRole) {
248
335
  var reservation = yield _reservationModel.default.findById(reservationId);
249
336
  if (!reservation) {
250
337
  throw new Error('Reserva no encontrada.');
@@ -264,8 +351,8 @@ var cancelReservation = /*#__PURE__*/function () {
264
351
  message: 'Reserva cancelada exitosamente.'
265
352
  };
266
353
  });
267
- return function cancelReservation(_x6, _x7, _x8) {
268
- return _ref4.apply(this, arguments);
354
+ return function cancelReservation(_x8, _x9, _x10) {
355
+ return _ref5.apply(this, arguments);
269
356
  };
270
357
  }();
271
358
 
@@ -275,12 +362,12 @@ var cancelReservation = /*#__PURE__*/function () {
275
362
  * @returns {Promise<object|null>} - El documento de la reservación o null si no existe.
276
363
  */
277
364
  var getReservationById = /*#__PURE__*/function () {
278
- var _ref5 = _asyncToGenerator(function* (reservationId) {
365
+ var _ref6 = _asyncToGenerator(function* (reservationId) {
279
366
  var reservation = yield _reservationModel.default.findById(reservationId).populate('bikeId', 'name location').populate('userId', 'firstName lastName email');
280
367
  return reservation;
281
368
  });
282
- return function getReservationById(_x9) {
283
- return _ref5.apply(this, arguments);
369
+ return function getReservationById(_x11) {
370
+ return _ref6.apply(this, arguments);
284
371
  };
285
372
  }();
286
373
 
@@ -291,7 +378,7 @@ var getReservationById = /*#__PURE__*/function () {
291
378
  * @throws {Error} - Si la reserva no se encuentra o no se puede cancelar.
292
379
  */
293
380
  var cancelReservationById = /*#__PURE__*/function () {
294
- var _ref6 = _asyncToGenerator(function* (reservationId) {
381
+ var _ref7 = _asyncToGenerator(function* (reservationId) {
295
382
  var reservation = yield _reservationModel.default.findById(reservationId);
296
383
  if (!reservation) {
297
384
  throw new Error('Reserva no encontrada.');
@@ -307,8 +394,8 @@ var cancelReservationById = /*#__PURE__*/function () {
307
394
  deletedReservation: reservation
308
395
  };
309
396
  });
310
- return function cancelReservationById(_x10) {
311
- return _ref6.apply(this, arguments);
397
+ return function cancelReservationById(_x12) {
398
+ return _ref7.apply(this, arguments);
312
399
  };
313
400
  }();
314
401
 
@@ -319,7 +406,7 @@ var cancelReservationById = /*#__PURE__*/function () {
319
406
  * @throws {Error} - Si no se proporciona el ID de usuario.
320
407
  */
321
408
  var getReservationsByUserId = /*#__PURE__*/function () {
322
- var _ref7 = _asyncToGenerator(function* (userId) {
409
+ var _ref8 = _asyncToGenerator(function* (userId) {
323
410
  if (!userId) {
324
411
  throw new Error('El ID de usuario es requerido para obtener las reservaciones.');
325
412
  }
@@ -332,8 +419,8 @@ var getReservationsByUserId = /*#__PURE__*/function () {
332
419
 
333
420
  return reservations;
334
421
  });
335
- return function getReservationsByUserId(_x11) {
336
- return _ref7.apply(this, arguments);
422
+ return function getReservationsByUserId(_x13) {
423
+ return _ref8.apply(this, arguments);
337
424
  };
338
425
  }();
339
426
  var _default = exports.default = {
@@ -344,5 +431,8 @@ var _default = exports.default = {
344
431
  cancelReservationById,
345
432
  isBikeReserved,
346
433
  // Keep exporting isBikeReserved if used elsewhere, otherwise could be removed if only internal
347
- getReservationsByUserId
434
+ getReservationsByUserId,
435
+ isTimeSlotAvailableForReservation,
436
+ // Export for potential use in API layer
437
+ extractTimeSlotFromTimestamp // Export for potential use in API layer
348
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
+ };