219 lines
6.7 KiB
TypeScript
219 lines
6.7 KiB
TypeScript
import { Router } from "@oak/oak";
|
|
import { db } from "../config/database.ts";
|
|
import { authenticateToken, getCurrentUser } from "../middleware/auth.ts";
|
|
|
|
const router = new Router();
|
|
|
|
interface Activity {
|
|
id: number;
|
|
sub_department_id: number;
|
|
name: string;
|
|
unit_of_measurement: string;
|
|
created_at: string;
|
|
sub_department_name?: string;
|
|
department_id?: number;
|
|
department_name?: string;
|
|
}
|
|
|
|
// Get all activities (with optional filters)
|
|
router.get("/", authenticateToken, async (ctx) => {
|
|
try {
|
|
const params = ctx.request.url.searchParams;
|
|
const subDepartmentId = params.get("subDepartmentId");
|
|
const departmentId = params.get("departmentId");
|
|
|
|
let query = `
|
|
SELECT a.id, a.sub_department_id, a.name, a.unit_of_measurement, a.created_at,
|
|
sd.name as sub_department_name,
|
|
sd.department_id,
|
|
d.name as department_name
|
|
FROM activities a
|
|
JOIN sub_departments sd ON a.sub_department_id = sd.id
|
|
JOIN departments d ON sd.department_id = d.id
|
|
WHERE 1=1
|
|
`;
|
|
const queryParams: unknown[] = [];
|
|
|
|
if (subDepartmentId) {
|
|
query += " AND a.sub_department_id = ?";
|
|
queryParams.push(subDepartmentId);
|
|
}
|
|
|
|
if (departmentId) {
|
|
query += " AND sd.department_id = ?";
|
|
queryParams.push(departmentId);
|
|
}
|
|
|
|
query += " ORDER BY d.name, sd.name, a.name";
|
|
|
|
const activities = await db.query<Activity[]>(query, queryParams);
|
|
ctx.response.body = activities;
|
|
} catch (error) {
|
|
console.error("Get activities error:", error);
|
|
ctx.response.status = 500;
|
|
ctx.response.body = { error: "Internal server error" };
|
|
}
|
|
});
|
|
|
|
// Get activity by ID
|
|
router.get("/:id", authenticateToken, async (ctx) => {
|
|
try {
|
|
const activityId = ctx.params.id;
|
|
|
|
const activities = await db.query<Activity[]>(
|
|
`SELECT a.id, a.sub_department_id, a.name, a.unit_of_measurement, a.created_at,
|
|
sd.name as sub_department_name,
|
|
sd.department_id,
|
|
d.name as department_name
|
|
FROM activities a
|
|
JOIN sub_departments sd ON a.sub_department_id = sd.id
|
|
JOIN departments d ON sd.department_id = d.id
|
|
WHERE a.id = ?`,
|
|
[activityId]
|
|
);
|
|
|
|
if (activities.length === 0) {
|
|
ctx.response.status = 404;
|
|
ctx.response.body = { error: "Activity not found" };
|
|
return;
|
|
}
|
|
|
|
ctx.response.body = activities[0];
|
|
} catch (error) {
|
|
console.error("Get activity error:", error);
|
|
ctx.response.status = 500;
|
|
ctx.response.body = { error: "Internal server error" };
|
|
}
|
|
});
|
|
|
|
// Create activity (SuperAdmin or Supervisor for their own department)
|
|
router.post("/", authenticateToken, async (ctx) => {
|
|
try {
|
|
const user = getCurrentUser(ctx);
|
|
const body = await ctx.request.body.json();
|
|
const { sub_department_id, name, unit_of_measurement } = body;
|
|
|
|
if (!sub_department_id || !name) {
|
|
ctx.response.status = 400;
|
|
ctx.response.body = { error: "Sub-department ID and name are required" };
|
|
return;
|
|
}
|
|
|
|
// Get the sub-department to check department ownership
|
|
const subDepts = await db.query<{ department_id: number }[]>(
|
|
"SELECT department_id FROM sub_departments WHERE id = ?",
|
|
[sub_department_id]
|
|
);
|
|
|
|
if (subDepts.length === 0) {
|
|
ctx.response.status = 404;
|
|
ctx.response.body = { error: "Sub-department not found" };
|
|
return;
|
|
}
|
|
|
|
const subDeptDepartmentId = subDepts[0].department_id;
|
|
|
|
// Check authorization
|
|
if (user.role === 'Supervisor' && user.departmentId !== subDeptDepartmentId) {
|
|
ctx.response.status = 403;
|
|
ctx.response.body = { error: "You can only create activities for your own department" };
|
|
return;
|
|
}
|
|
|
|
if (user.role !== 'SuperAdmin' && user.role !== 'Supervisor') {
|
|
ctx.response.status = 403;
|
|
ctx.response.body = { error: "Unauthorized" };
|
|
return;
|
|
}
|
|
|
|
const result = await db.execute(
|
|
"INSERT INTO activities (sub_department_id, name, unit_of_measurement) VALUES (?, ?, ?)",
|
|
[sub_department_id, name, unit_of_measurement || "Per Bag"]
|
|
);
|
|
|
|
ctx.response.status = 201;
|
|
ctx.response.body = {
|
|
id: result.lastInsertId,
|
|
message: "Activity created successfully"
|
|
};
|
|
} catch (error) {
|
|
const err = error as { code?: string };
|
|
if (err.code === "ER_DUP_ENTRY") {
|
|
ctx.response.status = 400;
|
|
ctx.response.body = { error: "Activity already exists in this sub-department" };
|
|
return;
|
|
}
|
|
console.error("Create activity error:", error);
|
|
ctx.response.status = 500;
|
|
ctx.response.body = { error: "Internal server error" };
|
|
}
|
|
});
|
|
|
|
// Update activity
|
|
router.put("/:id", authenticateToken, async (ctx) => {
|
|
try {
|
|
const activityId = ctx.params.id;
|
|
const body = await ctx.request.body.json();
|
|
const { name, unit_of_measurement } = body;
|
|
|
|
await db.execute(
|
|
"UPDATE activities SET name = ?, unit_of_measurement = ? WHERE id = ?",
|
|
[name, unit_of_measurement, activityId]
|
|
);
|
|
|
|
ctx.response.body = { message: "Activity updated successfully" };
|
|
} catch (error) {
|
|
console.error("Update activity error:", error);
|
|
ctx.response.status = 500;
|
|
ctx.response.body = { error: "Internal server error" };
|
|
}
|
|
});
|
|
|
|
// Delete activity (SuperAdmin or Supervisor for their own department)
|
|
router.delete("/:id", authenticateToken, async (ctx) => {
|
|
try {
|
|
const user = getCurrentUser(ctx);
|
|
const activityId = ctx.params.id;
|
|
|
|
// Get the activity and its sub-department to check department ownership
|
|
const activities = await db.query<Activity[]>(
|
|
`SELECT a.*, sd.department_id
|
|
FROM activities a
|
|
JOIN sub_departments sd ON a.sub_department_id = sd.id
|
|
WHERE a.id = ?`,
|
|
[activityId]
|
|
);
|
|
|
|
if (activities.length === 0) {
|
|
ctx.response.status = 404;
|
|
ctx.response.body = { error: "Activity not found" };
|
|
return;
|
|
}
|
|
|
|
const activity = activities[0] as Activity & { department_id: number };
|
|
|
|
// Check authorization
|
|
if (user.role === 'Supervisor' && user.departmentId !== activity.department_id) {
|
|
ctx.response.status = 403;
|
|
ctx.response.body = { error: "You can only delete activities from your own department" };
|
|
return;
|
|
}
|
|
|
|
if (user.role !== 'SuperAdmin' && user.role !== 'Supervisor') {
|
|
ctx.response.status = 403;
|
|
ctx.response.body = { error: "Unauthorized" };
|
|
return;
|
|
}
|
|
|
|
await db.execute("DELETE FROM activities WHERE id = ?", [activityId]);
|
|
|
|
ctx.response.body = { message: "Activity deleted successfully" };
|
|
} catch (error) {
|
|
console.error("Delete activity error:", error);
|
|
ctx.response.status = 500;
|
|
ctx.response.body = { error: "Internal server error" };
|
|
}
|
|
});
|
|
|
|
export default router;
|