Skip to content

Commit a70746e

Browse files
authored
Merge pull request #38 from Code-the-Dream-School/MedControllerErrorHandling
Med controller error handling
2 parents 7e545fc + d437fce commit a70746e

File tree

6 files changed

+209
-100
lines changed

6 files changed

+209
-100
lines changed
+114-52
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,145 @@
11
const Medication = require("../models/Medication");
22
const User = require("../models/UserModel");
3+
const DispenseLog = require("../models/DispenseLog");
34
const { StatusCodes } = require("http-status-codes");
45
const { NotFoundError } = require("../errors");
56

6-
// Fetch all medications
7-
const getMedications = async (req, res) => {
8-
const medications = await Medication.find();
9-
res.status(StatusCodes.OK).json({ success: true, data: medications });
10-
console.log("Fetch All Medications");
7+
const getMedications = async (req, res, next) => {
8+
try {
9+
const medications = await Medication.find();
10+
res.status(StatusCodes.OK).json({ success: true, data: medications });
11+
} catch (error) {
12+
next(error);
13+
}
1114
};
1215

13-
// Fetch a Single medication
14-
const getMedication = async (req, res) => {
15-
const { id } = req.params;
16-
const medication = await Medication.findById(id);
17-
if (!medication) {
18-
throw new NotFoundError(`No medication found with id: ${id}`);
16+
const getMedication = async (req, res, next) => {
17+
try {
18+
const { id } = req.params;
19+
const medication = await Medication.findById(id);
20+
if (!medication) {
21+
throw new NotFoundError(`No medication found with id: ${id}`);
22+
}
23+
res.status(StatusCodes.OK).json({ success: true, data: medication });
24+
} catch (error) {
25+
next(error);
1926
}
20-
res.status(StatusCodes.OK).json({ success: true, data: medication });
21-
console.log("Fetch Single Medication");
2227
};
2328

24-
// Create a medication
25-
const createMedication = async (req, res) => {
29+
const createMedication = async (req, res, next) => {
2630
try {
27-
const userId = req.user.id; // Get the user ID from the request
28-
29-
// Fetch the user's name using the userId
31+
const userId = req.user.id;
3032
const user = await User.findById(userId);
3133
if (!user) {
3234
return res
33-
.status(404)
35+
.status(StatusCodes.NOT_FOUND)
3436
.json({ success: false, message: "User not found" });
3537
}
3638

37-
// Assign the user's Name, Id, and Store to the created med
3839
const medicationData = {
3940
...req.body,
40-
loggedBy: user.name, //Assign the user's name
41-
createdBy: user.id, // Assign the user's Id
42-
store: user.store, // Assign the user's store
41+
createdBy: user.id,
4342
};
44-
45-
// Create a new medication record with the user's name
4643
const medication = await Medication.create(medicationData);
47-
4844
res.status(StatusCodes.CREATED).json({ success: true, data: medication });
49-
console.log("Create Medication");
5045
} catch (error) {
51-
res
52-
.status(StatusCodes.INTERNAL_SERVER_ERROR)
53-
.json({ success: false, error: error.message });
54-
console.error("Error creating medication:", error);
46+
next(error);
47+
}
48+
};
49+
50+
const dispenseMedication = async (req, res, next) => {
51+
try {
52+
const { medicationId, quantity } = req.body;
53+
const medication = await Medication.findById(medicationId).populate({
54+
path: "createdBy",
55+
select: "store",
56+
});
57+
58+
if (!medication) {
59+
return res
60+
.status(StatusCodes.NOT_FOUND)
61+
.json({ success: false, message: "Medication not Found" });
62+
}
63+
64+
if (medication.createdBy.store !== req.user.store) {
65+
return res.status(StatusCodes.FORBIDDEN).json({
66+
success: false,
67+
message:
68+
"You are not authorized to dispense medication from this store.",
69+
});
70+
}
71+
72+
if (medication.quantity < quantity) {
73+
return res.status(StatusCodes.BAD_REQUEST).json({
74+
success: false,
75+
message: "Insufficient stock available",
76+
});
77+
}
78+
79+
medication.quantity -= quantity;
80+
await medication.save();
81+
82+
const log = await DispenseLog.create({
83+
medicationId,
84+
userId: req.user.id,
85+
quantity,
86+
dispenseDate: new Date(),
87+
});
88+
89+
const populatedLog = await log.populate([
90+
{ path: "medicationId", select: "name ndc lot" },
91+
{ path: "userId", select: "name store" },
92+
]);
93+
94+
res.status(StatusCodes.OK).json({
95+
success: true,
96+
message: "Medication dispensed successfully",
97+
log: populatedLog,
98+
});
99+
} catch (error) {
100+
next(error);
101+
}
102+
};
103+
104+
const getDispenseLogs = async (req, res, next) => {
105+
try {
106+
const logs = await DispenseLog.find();
107+
res.status(StatusCodes.OK).json({ success: true, data: logs });
108+
} catch (error) {
109+
next(error);
55110
}
56111
};
57112

58-
// Update an existing medication
59-
const updateMedication = async (req, res) => {
60-
const { id } = req.params;
61-
const medication = await Medication.findByIdAndUpdate(id, req.body, {
62-
new: true,
63-
runValidators: true,
64-
});
65-
if (!medication) {
66-
throw new NotFoundError(`No medication found with id: ${id}`);
113+
const updateMedication = async (req, res, next) => {
114+
try {
115+
const { id } = req.params;
116+
const medication = await Medication.findByIdAndUpdate(id, req.body, {
117+
new: true,
118+
runValidators: true,
119+
});
120+
if (!medication) {
121+
throw new NotFoundError(`No medication found with id: ${id}`);
122+
}
123+
res.status(StatusCodes.OK).json({ success: true, data: medication });
124+
} catch (error) {
125+
next(error);
67126
}
68-
res.status(StatusCodes.OK).json({ success: true, data: medication });
69-
console.log("Changes a medication");
70127
};
71128

72-
// Delete a medication
73-
const deleteMedication = async (req, res) => {
74-
const { id } = req.params;
75-
const medication = await Medication.findByIdAndDelete(id);
76-
if (!medication) {
77-
throw new NotFoundError(`No medication found with id: ${id}`);
129+
const deleteMedication = async (req, res, next) => {
130+
try {
131+
const { id } = req.params;
132+
const medication = await Medication.findByIdAndDelete(id);
133+
if (!medication) {
134+
throw new NotFoundError(`No medication found with id: ${id}`);
135+
}
136+
res.status(StatusCodes.OK).json({
137+
success: true,
138+
message: "Medication deleted successfully",
139+
});
140+
} catch (error) {
141+
next(error);
78142
}
79-
res
80-
.status(StatusCodes.OK)
81-
.json({ success: true, message: "Medication deleted successfully" });
82-
console.log("Delete Medication");
83143
};
84144

85145
module.exports = {
@@ -88,4 +148,6 @@ module.exports = {
88148
createMedication,
89149
updateMedication,
90150
deleteMedication,
151+
dispenseMedication,
152+
getDispenseLogs,
91153
};

src/middleware/authMiddleware.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const jwt = require("jsonwebtoken");
2+
const User = require("../models/UserModel"); // Adjust the path to your User model
23

3-
const authenticate = (req, res, next) => {
4+
const authenticate = async (req, res, next) => {
45
const authHeader = req.header("Authorization");
56

67
// Check if the Authorization header is present
@@ -11,14 +12,23 @@ const authenticate = (req, res, next) => {
1112
});
1213
}
1314

14-
const token = authHeader.split(" ")[1]; // take token from header
15+
const token = authHeader.split(" ")[1]; // Extract token from header
1516

1617
try {
1718
// Verify token
1819
const decoded = jwt.verify(token, process.env.JWT_SECRET);
1920

20-
// Attach the user data (from token) to the request object
21-
req.user = { id: decoded.id, role: decoded.role };
21+
// Fetch the full user details, including `store`
22+
const user = await User.findById(decoded.id);
23+
if (!user) {
24+
return res.status(404).json({
25+
success: false,
26+
message: "User not found.",
27+
});
28+
}
29+
30+
// Attach the full user object to the request
31+
req.user = { id: user.id, role: user.role, store: user.store };
2232
next();
2333
} catch (err) {
2434
return res.status(401).json({

src/models/DispenseLog.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const mongoose = require("mongoose");
2+
3+
const dispenseLogSchema = new mongoose.Schema(
4+
{
5+
medicationId: {
6+
type: mongoose.Schema.Types.ObjectId,
7+
ref: "Medication",
8+
required: true,
9+
},
10+
userId: {
11+
type: mongoose.Schema.Types.ObjectId,
12+
ref: "User",
13+
required: true,
14+
},
15+
quantity: {
16+
type: Number,
17+
required: true,
18+
min: [1, "Dispensed Quantity must be at least 1"],
19+
},
20+
dispenseDate: {
21+
type: Date,
22+
default: Date.now,
23+
required: true,
24+
},
25+
},
26+
{ timestamps: true },
27+
);
28+
29+
module.exports = mongoose.model("DispenseLog", dispenseLogSchema);

src/models/Medication.js

+1-10
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,8 @@ const medicationSchema = new mongoose.Schema(
3636
required: [true, "Please provide NDC Number"],
3737
unique: true,
3838
},
39-
store: {
40-
type: String,
41-
ref: "User",
42-
required: [true, "Please provide Store Name"],
43-
},
44-
loggedBy: {
45-
type: String,
46-
ref: "User",
47-
},
4839
createdBy: {
49-
type: String,
40+
type: mongoose.Schema.Types.ObjectId,
5041
ref: "User",
5142
required: [true, "Please provide the creator's user ID"],
5243
},

src/routes/medicationRoutes.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const express = require("express");
22
const authenticate = require("../middleware/authMiddleware");
3-
43
const roleMiddleware = require("../middleware/roleMiddleware");
54

65
const {
@@ -9,6 +8,8 @@ const {
98
createMedication,
109
updateMedication,
1110
deleteMedication,
11+
dispenseMedication,
12+
getDispenseLogs,
1213
} = require("../controllers/medicationController");
1314

1415
const router = express.Router();
@@ -54,4 +55,20 @@ router.delete(
5455
deleteMedication,
5556
);
5657

58+
// POST /inventory/dispense Dispense medication
59+
router.post(
60+
"/dispense",
61+
authenticate,
62+
roleMiddleware(["admin", "clerk", "inventoryManager"]),
63+
dispenseMedication,
64+
);
65+
66+
// Dispense Log Stats
67+
router.get(
68+
"/dispense-logs",
69+
authenticate,
70+
roleMiddleware(["admin", "clerk", "inventoryManager"]),
71+
getDispenseLogs,
72+
);
73+
5774
module.exports = router;

0 commit comments

Comments
 (0)