|
1 | 1 | const mongoose = require('mongoose'); |
2 | 2 |
|
3 | 3 | const bmEquipmentController = (BuildingEquipment) => { |
| 4 | + const equipmentPopulateConfig = [ |
| 5 | + { path: 'itemType', select: '_id name description unit imageUrl category' }, |
| 6 | + { path: 'project', select: 'name' }, |
| 7 | + { path: 'userResponsible', select: '_id firstName lastName' }, |
| 8 | + { |
| 9 | + path: 'purchaseRecord', |
| 10 | + populate: { path: 'requestedBy', select: '_id firstName lastName' }, |
| 11 | + }, |
| 12 | + { |
| 13 | + path: 'updateRecord', |
| 14 | + populate: { path: 'createdBy', select: '_id firstName lastName' }, |
| 15 | + }, |
| 16 | + { |
| 17 | + path: 'logRecord', |
| 18 | + populate: [ |
| 19 | + { path: 'createdBy', select: '_id firstName lastName' }, |
| 20 | + { path: 'responsibleUser', select: '_id firstName lastName' }, |
| 21 | + ], |
| 22 | + }, |
| 23 | + ]; |
| 24 | + |
4 | 25 | const fetchSingleEquipment = async (req, res) => { |
5 | 26 | const { equipmentId } = req.params; |
6 | 27 | try { |
7 | 28 | BuildingEquipment.findById(equipmentId) |
8 | | - .populate([ |
9 | | - { |
10 | | - path: 'itemType', |
11 | | - select: '_id name description unit imageUrl category', |
12 | | - }, |
13 | | - { |
14 | | - path: 'project', |
15 | | - select: 'name', |
16 | | - }, |
17 | | - { |
18 | | - path: 'userResponsible', |
19 | | - select: '_id firstName lastName', |
20 | | - }, |
21 | | - { |
22 | | - path: 'purchaseRecord', |
23 | | - populate: { |
24 | | - path: 'requestedBy', |
25 | | - select: '_id firstName lastName', |
26 | | - }, |
27 | | - }, |
28 | | - { |
29 | | - path: 'updateRecord', |
30 | | - populate: { |
31 | | - path: 'createdBy', |
32 | | - select: '_id firstName lastName', |
33 | | - }, |
34 | | - }, |
35 | | - { |
36 | | - path: 'logRecord', |
37 | | - populate: [ |
38 | | - { |
39 | | - path: 'createdBy', |
40 | | - select: '_id firstName lastName', |
41 | | - }, |
42 | | - { |
43 | | - path: 'responsibleUser', |
44 | | - select: '_id firstName lastName', |
45 | | - }, |
46 | | - ], |
47 | | - }, |
48 | | - ]) |
| 29 | + .populate(equipmentPopulateConfig) |
49 | 30 | .exec() |
50 | 31 | .then((equipment) => res.status(200).send(equipment)) |
51 | 32 | .catch((error) => res.status(500).send(error)); |
@@ -140,6 +121,88 @@ const bmEquipmentController = (BuildingEquipment) => { |
140 | 121 | } |
141 | 122 | }; |
142 | 123 |
|
| 124 | + const validateEnumField = (value, allowedValues, fieldName) => { |
| 125 | + if (value && !allowedValues.includes(value)) { |
| 126 | + return `Invalid ${fieldName}. Allowed values: ${allowedValues.join(', ')}`; |
| 127 | + } |
| 128 | + return null; |
| 129 | + }; |
| 130 | + |
| 131 | + const updateEquipmentById = async (req, res) => { |
| 132 | + const { equipmentId } = req.params; |
| 133 | + const { projectId, purchaseStatus, currentUsage, condition } = req.body; |
| 134 | + |
| 135 | + if (!mongoose.Types.ObjectId.isValid(equipmentId)) { |
| 136 | + return res.status(400).send({ message: 'Invalid equipment ID.' }); |
| 137 | + } |
| 138 | + |
| 139 | + if (projectId && !mongoose.Types.ObjectId.isValid(projectId)) { |
| 140 | + return res.status(400).send({ message: 'Invalid project ID.' }); |
| 141 | + } |
| 142 | + |
| 143 | + const enumChecks = [ |
| 144 | + [purchaseStatus, ['Rental', 'Purchase', 'Needed', 'Purchased', 'Rented'], 'purchaseStatus'], |
| 145 | + [currentUsage, ['Operational', 'Under Maintenance', 'Out of Service'], 'currentUsage'], |
| 146 | + [ |
| 147 | + condition, |
| 148 | + [ |
| 149 | + 'Like New', |
| 150 | + 'Good', |
| 151 | + 'Worn', |
| 152 | + 'Lost', |
| 153 | + 'Needs Repair', |
| 154 | + 'Needs Replacing', |
| 155 | + 'New', |
| 156 | + 'Used', |
| 157 | + 'Refurbished', |
| 158 | + ], |
| 159 | + 'condition', |
| 160 | + ], |
| 161 | + ]; |
| 162 | + const validationError = enumChecks.reduce( |
| 163 | + (err, [value, allowed, name]) => err || validateEnumField(value, allowed, name), |
| 164 | + null, |
| 165 | + ); |
| 166 | + if (validationError) { |
| 167 | + return res.status(400).send({ message: validationError }); |
| 168 | + } |
| 169 | + |
| 170 | + try { |
| 171 | + const updateFields = {}; |
| 172 | + const fieldMap = { |
| 173 | + projectId: 'project', |
| 174 | + equipmentClass: 'equipmentClass', |
| 175 | + purchaseStatus: 'purchaseStatus', |
| 176 | + currentUsage: 'currentUsage', |
| 177 | + condition: 'condition', |
| 178 | + }; |
| 179 | + Object.entries(fieldMap).forEach(([bodyKey, schemaKey]) => { |
| 180 | + const val = req.body[bodyKey]; |
| 181 | + if (val !== undefined && val !== null) { |
| 182 | + updateFields[schemaKey] = val; |
| 183 | + } |
| 184 | + }); |
| 185 | + |
| 186 | + if (Object.keys(updateFields).length === 0) { |
| 187 | + return res.status(400).send({ message: 'No valid fields provided to update.' }); |
| 188 | + } |
| 189 | + |
| 190 | + await BuildingEquipment.updateOne({ _id: equipmentId }, { $set: updateFields }); |
| 191 | + |
| 192 | + const updatedEquipment = await BuildingEquipment.findById(equipmentId) |
| 193 | + .populate(equipmentPopulateConfig) |
| 194 | + .exec(); |
| 195 | + |
| 196 | + if (!updatedEquipment) { |
| 197 | + return res.status(404).send({ message: 'Equipment not found.' }); |
| 198 | + } |
| 199 | + |
| 200 | + return res.status(200).send(updatedEquipment); |
| 201 | + } catch (error) { |
| 202 | + return res.status(500).send({ message: error.message || 'Internal server error.' }); |
| 203 | + } |
| 204 | + }; |
| 205 | + |
143 | 206 | const updateLogRecords = async (req, res) => { |
144 | 207 | const { project: projectId } = req.query; |
145 | 208 | const updates = req.body; |
@@ -218,6 +281,7 @@ const bmEquipmentController = (BuildingEquipment) => { |
218 | 281 | fetchSingleEquipment, |
219 | 282 | bmPurchaseEquipments, |
220 | 283 | fetchBMEquipments, |
| 284 | + updateEquipmentById, |
221 | 285 | updateLogRecords, |
222 | 286 | }; |
223 | 287 | }; |
|
0 commit comments