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.
- package/dist/index.js +21 -0
- 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 +117 -27
- 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,
|
|
@@ -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
|
|
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.
|
|
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(
|
|
128
|
-
return
|
|
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
|
|
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(
|
|
228
|
-
return
|
|
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
|
|
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(
|
|
268
|
-
return
|
|
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
|
|
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(
|
|
283
|
-
return
|
|
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
|
|
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(
|
|
311
|
-
return
|
|
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
|
|
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(
|
|
336
|
-
return
|
|
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
|
+
};
|