Skip to content

Commit 44fc633

Browse files
Merge pull request #2054 from OneCommunityGlobal/SaiKrishna_EditableAndSelectableFieldsInEquipmentPage
SaiKrishna_EditableAndSelectableFieldsInEquipmentBackEnd
2 parents 2b1746a + b4cae23 commit 44fc633

6 files changed

Lines changed: 232 additions & 104 deletions

File tree

src/controllers/bmdashboard/bmEquipmentController.js

Lines changed: 105 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,32 @@
11
const mongoose = require('mongoose');
22

33
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+
425
const fetchSingleEquipment = async (req, res) => {
526
const { equipmentId } = req.params;
627
try {
728
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)
4930
.exec()
5031
.then((equipment) => res.status(200).send(equipment))
5132
.catch((error) => res.status(500).send(error));
@@ -140,6 +121,88 @@ const bmEquipmentController = (BuildingEquipment) => {
140121
}
141122
};
142123

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+
143206
const updateLogRecords = async (req, res) => {
144207
const { project: projectId } = req.query;
145208
const updates = req.body;
@@ -218,6 +281,7 @@ const bmEquipmentController = (BuildingEquipment) => {
218281
fetchSingleEquipment,
219282
bmPurchaseEquipments,
220283
fetchBMEquipments,
284+
updateEquipmentById,
221285
updateLogRecords,
222286
};
223287
};

src/models/bmdashboard/buildingEquipment.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ const mongoose = require('mongoose');
33
const { Schema } = mongoose;
44

55
const buildingEquipment = new Schema({
6-
itemType: { type: mongoose.SchemaTypes.ObjectId, ref: 'buildingInventoryType' },
6+
itemType: { type: mongoose.SchemaTypes.ObjectId, ref: 'invTypeBase' },
77
project: { type: mongoose.SchemaTypes.ObjectId, ref: 'buildingProject' },
88
code: { type: Number }, // add function to create code for on-site tool tracking.Not marked as 'required' as it breaks the tool purchase form functionality.
9-
purchaseStatus: { type: String, enum: ['Rental', 'Purchase'] },
9+
purchaseStatus: { type: String, enum: ['Rental', 'Purchase', 'Purchased', 'Rented'] },
1010
// add discriminator based on rental or purchase so these fields are required if tool is rented. Not marked as 'required' as it breaks the tool purchase form functionality.
1111
rentedOnDate: Date,
1212
rentalDue: Date,
1313
userResponsible: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' },
14+
equipmentClass: { type: String },
15+
currentUsage: { type: String, enum: ['Operational', 'Under Maintenance', 'Out of Service'] },
16+
condition: { type: String, enum: ['New', 'Used', 'Refurbished'] },
1417
purchaseRecord: [
1518
{
1619
// track purchase/rental requests

0 commit comments

Comments
 (0)