goldstars-services 1.0.70 → 1.0.73
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 +93 -0
- package/dist/models/user.model.js +32 -0
- package/dist/models/weeklyScheduleTemplate.model.js +76 -0
- package/dist/scripts/migrateInitialSchedules.js +331 -0
- package/dist/services/reservation.service.js +122 -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,75 @@ 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
|
+
var timeSlot = extractTimeSlotFromTimestamp(timestamp);
|
|
51
|
+
|
|
52
|
+
// 1. Verificar excepciones (tienen prioridad)
|
|
53
|
+
var exceptions = yield _scheduleExceptionService.default.getExceptionsForDate(location, timestamp);
|
|
54
|
+
if (exceptions.length > 0) {
|
|
55
|
+
for (var exc of exceptions) {
|
|
56
|
+
// Si está cerrado, no disponible
|
|
57
|
+
if (exc.exceptionType === 'CLOSED') {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Si el slot específico está bloqueado
|
|
62
|
+
if (exc.exceptionType === 'SLOT_BLOCKED' && exc.blockedTimeSlot === timeSlot) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Si hay horarios custom, usar esos
|
|
67
|
+
if (exc.exceptionType === 'CUSTOM_HOURS') {
|
|
68
|
+
return exc.customTimeSlots.some(s => s.time === timeSlot && s.isActive);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 2. Si no hay excepciones, usar template semanal
|
|
74
|
+
var weeklySchedule = yield _weeklyScheduleTemplateService.default.getWeeklyScheduleForDay(location, dayOfWeek);
|
|
75
|
+
if (!weeklySchedule) {
|
|
76
|
+
return false; // No hay horarios configurados para este día
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Verificar si el time slot está en el template y está activo
|
|
80
|
+
return weeklySchedule.timeSlots.some(s => s.time === timeSlot && s.isActive);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error('Error verificando disponibilidad de horario:', error);
|
|
83
|
+
return false; // En caso de error, no permitir la reserva
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return function isTimeSlotAvailableForReservation(_x, _x2) {
|
|
87
|
+
return _ref.apply(this, arguments);
|
|
88
|
+
};
|
|
89
|
+
}();
|
|
90
|
+
|
|
19
91
|
/**
|
|
20
92
|
* Checks if a bike is already reserved for a specific timestamp.
|
|
21
93
|
* @param {string} bikeId - The ID of the bike.
|
|
@@ -23,7 +95,7 @@ function _asyncToGenerator(n) { return function () { var t = this, e = arguments
|
|
|
23
95
|
* @returns {Promise<boolean>} - True if the bike is already reserved, false otherwise.
|
|
24
96
|
*/
|
|
25
97
|
var isBikeReserved = /*#__PURE__*/function () {
|
|
26
|
-
var
|
|
98
|
+
var _ref2 = _asyncToGenerator(function* (bikeId, timestamp) {
|
|
27
99
|
var searchTimestamp = new Date(timestamp);
|
|
28
100
|
if (isNaN(searchTimestamp.getTime())) {
|
|
29
101
|
throw new Error('Timestamp inválido proporcionado a isBikeReserved.');
|
|
@@ -36,8 +108,8 @@ var isBikeReserved = /*#__PURE__*/function () {
|
|
|
36
108
|
});
|
|
37
109
|
return !!existingReservation;
|
|
38
110
|
});
|
|
39
|
-
return function isBikeReserved(
|
|
40
|
-
return
|
|
111
|
+
return function isBikeReserved(_x3, _x4) {
|
|
112
|
+
return _ref2.apply(this, arguments);
|
|
41
113
|
};
|
|
42
114
|
}();
|
|
43
115
|
|
|
@@ -52,7 +124,7 @@ var isBikeReserved = /*#__PURE__*/function () {
|
|
|
52
124
|
* @throws {Error} - If bike not found, is instructor bike, timestamp invalid, or already reserved.
|
|
53
125
|
*/
|
|
54
126
|
var createReservation = /*#__PURE__*/function () {
|
|
55
|
-
var
|
|
127
|
+
var _ref3 = _asyncToGenerator(function* (reservationData) {
|
|
56
128
|
var {
|
|
57
129
|
userId,
|
|
58
130
|
bikeId,
|
|
@@ -68,7 +140,14 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
68
140
|
|
|
69
141
|
// 1. Validaciones por usuario solo aplican cuando hay usuario asociado
|
|
70
142
|
if (userId) {
|
|
71
|
-
// 1.a
|
|
143
|
+
// 1.a Verificar suspensión de usuario
|
|
144
|
+
var suspensionCheck = yield _userSuspensionService.default.checkUserSuspension(userId, 'bikes');
|
|
145
|
+
if (suspensionCheck.isSuspended) {
|
|
146
|
+
var untilMessage = suspensionCheck.suspendedUntil ? " hasta ".concat(new Date(suspensionCheck.suspendedUntil).toLocaleDateString('es-VE')) : ' indefinidamente';
|
|
147
|
+
throw new Error("Tu cuenta est\xE1 suspendida".concat(untilMessage, ". Raz\xF3n: ").concat(suspensionCheck.reason));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 1.b Check if user already has a reservation for this EXACT timestamp
|
|
72
151
|
var existingReservationSameSlot = yield _reservationModel.default.findOne({
|
|
73
152
|
userId,
|
|
74
153
|
timestamp: reservationTimestamp
|
|
@@ -77,7 +156,7 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
77
156
|
throw new Error('Ya tienes una reserva agendada para esta fecha y hora.');
|
|
78
157
|
}
|
|
79
158
|
|
|
80
|
-
// 1.
|
|
159
|
+
// 1.c Check if user already has an UPCOMING reservation
|
|
81
160
|
var now = new Date();
|
|
82
161
|
var existingUpcomingReservation = yield _reservationModel.default.findOne({
|
|
83
162
|
userId,
|
|
@@ -86,13 +165,16 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
86
165
|
} // Find reservations where the timestamp is now or in the future
|
|
87
166
|
});
|
|
88
167
|
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
168
|
throw new Error('Ya tienes una reserva activa. Debes esperar a que pase para agendar otra.');
|
|
93
169
|
}
|
|
94
170
|
}
|
|
95
171
|
|
|
172
|
+
// 2. Verificar disponibilidad de horario (templates y excepciones)
|
|
173
|
+
var isSlotAvailable = yield isTimeSlotAvailableForReservation(location, reservationTimestamp);
|
|
174
|
+
if (!isSlotAvailable) {
|
|
175
|
+
throw new Error('Este horario no está disponible para reservas en esta ubicación.');
|
|
176
|
+
}
|
|
177
|
+
|
|
96
178
|
// --- END NEW VALIDATIONS ---
|
|
97
179
|
|
|
98
180
|
// 1. Validate Bike
|
|
@@ -124,8 +206,8 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
124
206
|
yield newReservation.save();
|
|
125
207
|
return newReservation;
|
|
126
208
|
});
|
|
127
|
-
return function createReservation(
|
|
128
|
-
return
|
|
209
|
+
return function createReservation(_x5) {
|
|
210
|
+
return _ref3.apply(this, arguments);
|
|
129
211
|
};
|
|
130
212
|
}();
|
|
131
213
|
|
|
@@ -137,13 +219,23 @@ var createReservation = /*#__PURE__*/function () {
|
|
|
137
219
|
* @returns {Promise<Array<object>>} - An array of bike objects, each with an added 'reservationStatus' field.
|
|
138
220
|
*/
|
|
139
221
|
var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
140
|
-
var
|
|
222
|
+
var _ref4 = _asyncToGenerator(function* (location, timestamp) {
|
|
141
223
|
var includeInstructor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
142
224
|
var checkTimestamp = new Date(timestamp);
|
|
143
225
|
if (isNaN(checkTimestamp.getTime())) {
|
|
144
226
|
throw new Error('Timestamp inválido proporcionado para obtener disponibilidad.');
|
|
145
227
|
}
|
|
146
228
|
|
|
229
|
+
// ===== NUEVA VALIDACIÓN: Verificar si el horario está disponible en el nuevo sistema =====
|
|
230
|
+
var isSlotAvailable = yield isTimeSlotAvailableForReservation(location, checkTimestamp);
|
|
231
|
+
if (!isSlotAvailable) {
|
|
232
|
+
// Si el horario no está configurado en WeeklyScheduleTemplate o ScheduleException,
|
|
233
|
+
// retornar array vacío (no hay horarios disponibles)
|
|
234
|
+
console.log("Horario no disponible para ".concat(location, " en ").concat(checkTimestamp.toISOString()));
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
// ===== FIN NUEVA VALIDACIÓN =====
|
|
238
|
+
|
|
147
239
|
// 1. Find all bikes for the given location
|
|
148
240
|
var bikesInLocation = yield _bikeModel.default.find({
|
|
149
241
|
location
|
|
@@ -224,8 +316,8 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
|
224
316
|
});
|
|
225
317
|
return bikesWithStatus;
|
|
226
318
|
});
|
|
227
|
-
return function getBikeAvailabilityForSlot(
|
|
228
|
-
return
|
|
319
|
+
return function getBikeAvailabilityForSlot(_x6, _x7) {
|
|
320
|
+
return _ref4.apply(this, arguments);
|
|
229
321
|
};
|
|
230
322
|
}();
|
|
231
323
|
|
|
@@ -244,7 +336,7 @@ var getBikeAvailabilityForSlot = /*#__PURE__*/function () {
|
|
|
244
336
|
* @throws {Error} - If reservation not found or user is not authorized.
|
|
245
337
|
*/
|
|
246
338
|
var cancelReservation = /*#__PURE__*/function () {
|
|
247
|
-
var
|
|
339
|
+
var _ref5 = _asyncToGenerator(function* (reservationId, userId, userRole) {
|
|
248
340
|
var reservation = yield _reservationModel.default.findById(reservationId);
|
|
249
341
|
if (!reservation) {
|
|
250
342
|
throw new Error('Reserva no encontrada.');
|
|
@@ -264,8 +356,8 @@ var cancelReservation = /*#__PURE__*/function () {
|
|
|
264
356
|
message: 'Reserva cancelada exitosamente.'
|
|
265
357
|
};
|
|
266
358
|
});
|
|
267
|
-
return function cancelReservation(
|
|
268
|
-
return
|
|
359
|
+
return function cancelReservation(_x8, _x9, _x10) {
|
|
360
|
+
return _ref5.apply(this, arguments);
|
|
269
361
|
};
|
|
270
362
|
}();
|
|
271
363
|
|
|
@@ -275,12 +367,12 @@ var cancelReservation = /*#__PURE__*/function () {
|
|
|
275
367
|
* @returns {Promise<object|null>} - El documento de la reservación o null si no existe.
|
|
276
368
|
*/
|
|
277
369
|
var getReservationById = /*#__PURE__*/function () {
|
|
278
|
-
var
|
|
370
|
+
var _ref6 = _asyncToGenerator(function* (reservationId) {
|
|
279
371
|
var reservation = yield _reservationModel.default.findById(reservationId).populate('bikeId', 'name location').populate('userId', 'firstName lastName email');
|
|
280
372
|
return reservation;
|
|
281
373
|
});
|
|
282
|
-
return function getReservationById(
|
|
283
|
-
return
|
|
374
|
+
return function getReservationById(_x11) {
|
|
375
|
+
return _ref6.apply(this, arguments);
|
|
284
376
|
};
|
|
285
377
|
}();
|
|
286
378
|
|
|
@@ -291,7 +383,7 @@ var getReservationById = /*#__PURE__*/function () {
|
|
|
291
383
|
* @throws {Error} - Si la reserva no se encuentra o no se puede cancelar.
|
|
292
384
|
*/
|
|
293
385
|
var cancelReservationById = /*#__PURE__*/function () {
|
|
294
|
-
var
|
|
386
|
+
var _ref7 = _asyncToGenerator(function* (reservationId) {
|
|
295
387
|
var reservation = yield _reservationModel.default.findById(reservationId);
|
|
296
388
|
if (!reservation) {
|
|
297
389
|
throw new Error('Reserva no encontrada.');
|
|
@@ -307,8 +399,8 @@ var cancelReservationById = /*#__PURE__*/function () {
|
|
|
307
399
|
deletedReservation: reservation
|
|
308
400
|
};
|
|
309
401
|
});
|
|
310
|
-
return function cancelReservationById(
|
|
311
|
-
return
|
|
402
|
+
return function cancelReservationById(_x12) {
|
|
403
|
+
return _ref7.apply(this, arguments);
|
|
312
404
|
};
|
|
313
405
|
}();
|
|
314
406
|
|
|
@@ -319,7 +411,7 @@ var cancelReservationById = /*#__PURE__*/function () {
|
|
|
319
411
|
* @throws {Error} - Si no se proporciona el ID de usuario.
|
|
320
412
|
*/
|
|
321
413
|
var getReservationsByUserId = /*#__PURE__*/function () {
|
|
322
|
-
var
|
|
414
|
+
var _ref8 = _asyncToGenerator(function* (userId) {
|
|
323
415
|
if (!userId) {
|
|
324
416
|
throw new Error('El ID de usuario es requerido para obtener las reservaciones.');
|
|
325
417
|
}
|
|
@@ -332,8 +424,8 @@ var getReservationsByUserId = /*#__PURE__*/function () {
|
|
|
332
424
|
|
|
333
425
|
return reservations;
|
|
334
426
|
});
|
|
335
|
-
return function getReservationsByUserId(
|
|
336
|
-
return
|
|
427
|
+
return function getReservationsByUserId(_x13) {
|
|
428
|
+
return _ref8.apply(this, arguments);
|
|
337
429
|
};
|
|
338
430
|
}();
|
|
339
431
|
var _default = exports.default = {
|
|
@@ -344,5 +436,8 @@ var _default = exports.default = {
|
|
|
344
436
|
cancelReservationById,
|
|
345
437
|
isBikeReserved,
|
|
346
438
|
// Keep exporting isBikeReserved if used elsewhere, otherwise could be removed if only internal
|
|
347
|
-
getReservationsByUserId
|
|
439
|
+
getReservationsByUserId,
|
|
440
|
+
isTimeSlotAvailableForReservation,
|
|
441
|
+
// Export for potential use in API layer
|
|
442
|
+
extractTimeSlotFromTimestamp // Export for potential use in API layer
|
|
348
443
|
};
|
|
@@ -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
|
+
};
|