goldstars-services 1.0.40 → 1.0.42

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 CHANGED
@@ -51,6 +51,12 @@ Object.defineProperty(exports, "reportService", {
51
51
  return _report.default;
52
52
  }
53
53
  });
54
+ Object.defineProperty(exports, "reservationService", {
55
+ enumerable: true,
56
+ get: function get() {
57
+ return _reservation.default;
58
+ }
59
+ });
54
60
  var _db = _interopRequireDefault(require("./db"));
55
61
  var _user = _interopRequireDefault(require("./services/user.service"));
56
62
  var _config = _interopRequireDefault(require("./services/config.service"));
@@ -59,4 +65,5 @@ var _plan = _interopRequireDefault(require("./services/plan.service"));
59
65
  var _bank = _interopRequireDefault(require("./services/bank.service"));
60
66
  var _bike = _interopRequireDefault(require("./services/bike.service"));
61
67
  var _report = _interopRequireDefault(require("./services/report.service"));
68
+ var _reservation = _interopRequireDefault(require("./services/reservation.service"));
62
69
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _mongoose = _interopRequireDefault(require("mongoose"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ var reservationSchema = new _mongoose.default.Schema({
10
+ userId: {
11
+ type: _mongoose.default.Schema.Types.ObjectId,
12
+ ref: 'User',
13
+ // Assuming your user model is named 'User'
14
+ required: true
15
+ },
16
+ bikeId: {
17
+ type: _mongoose.default.Schema.Types.ObjectId,
18
+ ref: 'Bike',
19
+ // Assuming your bike model is named 'Bike'
20
+ required: true
21
+ },
22
+ date: {
23
+ type: Date,
24
+ // Store the specific date of the reservation
25
+ required: true
26
+ },
27
+ timeSlot: {
28
+ type: String,
29
+ // e.g., "7am", "5pm", "9:15am"
30
+ required: true
31
+ // Consider adding an enum later for validation if needed
32
+ // enum: ['7am', '8am', '9:15am', '5pm', '7pm']
33
+ },
34
+ location: {
35
+ type: String,
36
+ // e.g., "Sambil", "Las Virtudes"
37
+ required: true,
38
+ // Consider adding an enum later for validation
39
+ enum: ['Sambil Paraguaná', 'C.C Las Virtudes']
40
+ }
41
+ // Optional: Add a status field if needed (e.g., 'confirmed', 'cancelled')
42
+ // status: {
43
+ // type: String,
44
+ // enum: ['confirmed', 'cancelled'],
45
+ // default: 'confirmed',
46
+ // },
47
+ }, {
48
+ timestamps: true // Automatically adds createdAt and updatedAt fields
49
+ });
50
+
51
+ // Optional: Add indexes for faster querying based on common lookups
52
+ reservationSchema.index({
53
+ bikeId: 1,
54
+ date: 1,
55
+ timeSlot: 1
56
+ }, {
57
+ unique: true
58
+ }); // Prevent double booking the same bike/slot
59
+ reservationSchema.index({
60
+ userId: 1,
61
+ date: 1
62
+ }); // Quickly find user's reservations for a date
63
+
64
+ var Reservation = _mongoose.default.model('Reservation', reservationSchema);
65
+ var _default = exports.default = Reservation;
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getBikeAvailabilityForSlot = exports.createReservation = exports.cancelReservation = void 0;
7
+ var _reservationModel = _interopRequireDefault(require("../models/reservation.model.js"));
8
+ var _bikeModel = _interopRequireDefault(require("../models/bike.model.js"));
9
+ var _mongoose = _interopRequireDefault(require("mongoose"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ 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
+ 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; }
13
+ 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; }
14
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
15
+ 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); }
16
+ 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
+ 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
+ // Needed to check bike status/location
19
+ /**
20
+ * Checks if a bike is already reserved for a specific date and time slot.
21
+ * @param {string} bikeId - The ID of the bike.
22
+ * @param {Date} date - The reservation date.
23
+ * @param {string} timeSlot - The reservation time slot.
24
+ * @returns {Promise<boolean>} - True if the bike is already reserved, false otherwise.
25
+ */
26
+ var isBikeReserved = /*#__PURE__*/function () {
27
+ var _ref = _asyncToGenerator(function* (bikeId, date, timeSlot) {
28
+ var existingReservation = yield _reservationModel.default.findOne({
29
+ bikeId,
30
+ date,
31
+ timeSlot
32
+ // Optional: Add status check if cancelled reservations should allow re-booking
33
+ // status: 'confirmed',
34
+ });
35
+ return !!existingReservation;
36
+ });
37
+ return function isBikeReserved(_x, _x2, _x3) {
38
+ return _ref.apply(this, arguments);
39
+ };
40
+ }();
41
+
42
+ /**
43
+ * Creates a new reservation.
44
+ * @param {object} reservationData - Data for the new reservation.
45
+ * @param {string} reservationData.userId - User ID.
46
+ * @param {string} reservationData.bikeId - Bike ID.
47
+ * @param {Date} reservationData.date - Reservation date.
48
+ * @param {string} reservationData.timeSlot - Reservation time slot.
49
+ * @param {string} reservationData.location - Reservation location.
50
+ * @returns {Promise<object>} - The created reservation document.
51
+ * @throws {Error} - If bike not found, is instructor bike, or already reserved.
52
+ */
53
+ var createReservation = exports.createReservation = /*#__PURE__*/function () {
54
+ var _ref2 = _asyncToGenerator(function* (reservationData) {
55
+ var {
56
+ userId,
57
+ bikeId,
58
+ date,
59
+ timeSlot,
60
+ location
61
+ } = reservationData;
62
+
63
+ // 1. Validate Bike
64
+ var bike = yield _bikeModel.default.findById(bikeId);
65
+ if (!bike) {
66
+ throw new Error('Bicicleta no encontrada.');
67
+ }
68
+ if (bike.isInstructorBike) {
69
+ throw new Error('La bicicleta del instructor no se puede reservar.');
70
+ }
71
+ // Ensure the bike belongs to the specified location (optional but good practice)
72
+ if (bike.location !== location) {
73
+ throw new Error("La bicicleta ".concat(bike.name, " no pertenece a la ubicaci\xF3n ").concat(location, "."));
74
+ }
75
+
76
+ // 2. Check if already reserved
77
+ var alreadyReserved = yield isBikeReserved(bikeId, date, timeSlot);
78
+ if (alreadyReserved) {
79
+ throw new Error('Esta bicicleta ya está reservada para esta fecha y hora.');
80
+ }
81
+
82
+ // 3. Create Reservation (Add userId validation if needed)
83
+ var newReservation = new _reservationModel.default({
84
+ userId,
85
+ bikeId,
86
+ date,
87
+ timeSlot,
88
+ location
89
+ });
90
+ yield newReservation.save();
91
+ return newReservation;
92
+ });
93
+ return function createReservation(_x4) {
94
+ return _ref2.apply(this, arguments);
95
+ };
96
+ }();
97
+
98
+ /**
99
+ * Gets the availability status of all bikes for a specific location and date.
100
+ * @param {string} location - The location ('Sambil' or 'Las Virtudes').
101
+ * @param {Date} date - The date to check.
102
+ * @returns {Promise<Array<object>>} - An array of bike objects, each with an added 'reservationStatus' field.
103
+ */
104
+ var getBikeAvailabilityForSlot = exports.getBikeAvailabilityForSlot = /*#__PURE__*/function () {
105
+ var _ref3 = _asyncToGenerator(function* (location, date) {
106
+ // 1. Find all bikes for the given location
107
+ var bikesInLocation = yield _bikeModel.default.find({
108
+ location
109
+ }).lean(); // .lean() for plain JS objects
110
+
111
+ // 2. Find all reservations for the specific date
112
+ var reservations = yield _reservationModel.default.find({
113
+ date,
114
+ location // Filter by location as well for efficiency
115
+ // Optional: Add status filter if needed
116
+ // status: 'confirmed',
117
+ }).populate('userId', 'name email') // Populate user name/email for admin view
118
+ .lean();
119
+
120
+ // 3. Create a map of reserved bike IDs for quick lookup
121
+ var reservedBikeMap = new Map();
122
+ reservations.forEach(res => {
123
+ // Store the user info (or just true if user info isn't needed/allowed)
124
+ reservedBikeMap.set(res.bikeId.toString(), res.userId); // Store populated user object
125
+ });
126
+
127
+ // 4. Combine bike data with reservation status
128
+ var bikesWithStatus = bikesInLocation.map(bike => {
129
+ var bikeIdStr = bike._id.toString();
130
+ var reservedByUser = reservedBikeMap.get(bikeIdStr);
131
+ var reservationStatus;
132
+ if (bike.isInstructorBike) {
133
+ reservationStatus = {
134
+ status: 'instructor',
135
+ reservedBy: null
136
+ };
137
+ } else if (reservedByUser) {
138
+ // For admin: include user details. For regular user, this might be simplified later.
139
+ reservationStatus = {
140
+ status: 'agendada',
141
+ reservedBy: reservedByUser
142
+ };
143
+ } else if (bike.status === 'Disponible') {
144
+ // Check the bike's general status
145
+ reservationStatus = {
146
+ status: 'disponible',
147
+ reservedBy: null
148
+ };
149
+ } else {
150
+ // If bike's general status is 'No Disponible' or something else
151
+ reservationStatus = {
152
+ status: 'no_disponible_general',
153
+ reservedBy: null
154
+ };
155
+ }
156
+ return _objectSpread(_objectSpread({}, bike), {}, {
157
+ // Spread original bike data
158
+ reservationStatus // Add the specific status for this slot
159
+ });
160
+ });
161
+ return bikesWithStatus;
162
+ });
163
+ return function getBikeAvailabilityForSlot(_x5, _x6) {
164
+ return _ref3.apply(this, arguments);
165
+ };
166
+ }();
167
+
168
+ // Optional: Add functions for cancelling or fetching user-specific reservations later
169
+ /**
170
+ * Cancels a reservation.
171
+ * @param {string} reservationId - The ID of the reservation to cancel.
172
+ * @param {string} userId - The ID of the user attempting to cancel (for validation).
173
+ * @param {string} userRole - The role of the user ('admin' or other).
174
+ * @returns {Promise<object>} - The result of the deletion operation.
175
+ * @throws {Error} - If reservation not found or user is not authorized.
176
+ */
177
+ var cancelReservation = exports.cancelReservation = /*#__PURE__*/function () {
178
+ var _ref4 = _asyncToGenerator(function* (reservationId, userId, userRole) {
179
+ var reservation = yield _reservationModel.default.findById(reservationId);
180
+ if (!reservation) {
181
+ throw new Error('Reserva no encontrada.');
182
+ }
183
+
184
+ // Check authorization: User must own the reservation or be an admin
185
+ if (reservation.userId.toString() !== userId && userRole !== 'admin') {
186
+ throw new Error('No autorizado para cancelar esta reserva.');
187
+ }
188
+ var result = yield _reservationModel.default.deleteOne({
189
+ _id: reservationId
190
+ });
191
+ if (result.deletedCount === 0) {
192
+ throw new Error('No se pudo cancelar la reserva.');
193
+ }
194
+ return {
195
+ message: 'Reserva cancelada exitosamente.'
196
+ };
197
+ });
198
+ return function cancelReservation(_x7, _x8, _x9) {
199
+ return _ref4.apply(this, arguments);
200
+ };
201
+ }();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goldstars-services",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "description": "This is the services layer for GoldStars",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {