import { Router } from "@oak/oak"; import { db } from "../config/database.ts"; import { authenticateToken, authorize, getCurrentUser, } from "../middleware/auth.ts"; import type { JWTPayload, WorkAllocation } from "../types/index.ts"; const router = new Router(); // Get completed work allocations for reporting (with optional filters) router.get( "/completed-allocations", authenticateToken, authorize("Supervisor", "SuperAdmin"), async (ctx) => { try { const currentUser: JWTPayload = getCurrentUser(ctx); const params: URLSearchParams = ctx.request.url.searchParams; const startDate: string | null = params.get("startDate"); const endDate: string | null = params.get("endDate"); const departmentId: string | null = params.get("departmentId"); const contractorId: string | null = params.get("contractorId"); const employeeId: string | null = params.get("employeeId"); let query = ` SELECT wa.*, e.name as employee_name, e.username as employee_username, e.phone_number as employee_phone, s.name as supervisor_name, c.name as contractor_name, sd.name as sub_department_name, d.name as department_name, d.id as department_id FROM work_allocations wa JOIN users e ON wa.employee_id = e.id JOIN users s ON wa.supervisor_id = s.id JOIN users c ON wa.contractor_id = c.id LEFT JOIN sub_departments sd ON wa.sub_department_id = sd.id LEFT JOIN departments d ON e.department_id = d.id WHERE wa.status = 'Completed' `; const queryParams: unknown[] = []; // Role-based filtering - Supervisors can only see their department if (currentUser.role === "Supervisor") { query += " AND e.department_id = ?"; queryParams.push(currentUser.departmentId); } // Date range filter if (startDate) { query += " AND wa.completion_date >= ?"; queryParams.push(startDate); } if (endDate) { query += " AND wa.completion_date <= ?"; queryParams.push(endDate); } // Department filter (for SuperAdmin) if (departmentId && currentUser.role === "SuperAdmin") { query += " AND e.department_id = ?"; queryParams.push(departmentId); } // Contractor filter if (contractorId) { query += " AND wa.contractor_id = ?"; queryParams.push(contractorId); } // Employee filter if (employeeId) { query += " AND wa.employee_id = ?"; queryParams.push(employeeId); } query += " ORDER BY wa.completion_date DESC, wa.created_at DESC"; const allocations = await db.query(query, queryParams); // Calculate summary stats const totalAllocations = allocations.length; const totalAmount = allocations.reduce( (sum, a) => sum + (parseFloat(String(a.total_amount)) || parseFloat(String(a.rate)) || 0), 0, ); const totalUnits = allocations.reduce( (sum, a) => sum + (parseFloat(String(a.units)) || 0), 0, ); ctx.response.body = { allocations, summary: { totalAllocations, totalAmount: totalAmount.toFixed(2), totalUnits: totalUnits.toFixed(2), }, }; } catch (error) { console.error("Get completed allocations report error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }, ); // Get summary statistics for completed work router.get( "/summary", authenticateToken, authorize("Supervisor", "SuperAdmin"), async (ctx) => { try { const currentUser: JWTPayload = getCurrentUser(ctx); const params: URLSearchParams = ctx.request.url.searchParams; const startDate: string | null = params.get("startDate"); const endDate: string | null = params.get("endDate"); let departmentFilter = ""; const queryParams: unknown[] = []; if (currentUser.role === "Supervisor") { departmentFilter = " AND e.department_id = ?"; queryParams.push(currentUser.departmentId); } let dateFilter = ""; if (startDate) { dateFilter += " AND wa.completion_date >= ?"; queryParams.push(startDate); } if (endDate) { dateFilter += " AND wa.completion_date <= ?"; queryParams.push(endDate); } // Get summary by contractor const byContractor = await db.query( ` SELECT c.id as contractor_id, c.name as contractor_name, COUNT(*) as total_allocations, SUM(COALESCE(wa.total_amount, wa.rate, 0)) as total_amount, SUM(COALESCE(wa.units, 0)) as total_units FROM work_allocations wa JOIN users e ON wa.employee_id = e.id JOIN users c ON wa.contractor_id = c.id WHERE wa.status = 'Completed' ${departmentFilter} ${dateFilter} GROUP BY c.id, c.name ORDER BY total_amount DESC `, queryParams, ); // Get summary by sub-department const bySubDepartment = await db.query( ` SELECT sd.id as sub_department_id, sd.name as sub_department_name, d.name as department_name, COUNT(*) as total_allocations, SUM(COALESCE(wa.total_amount, wa.rate, 0)) as total_amount, SUM(COALESCE(wa.units, 0)) as total_units FROM work_allocations wa JOIN users e ON wa.employee_id = e.id LEFT JOIN sub_departments sd ON wa.sub_department_id = sd.id LEFT JOIN departments d ON sd.department_id = d.id WHERE wa.status = 'Completed' ${departmentFilter} ${dateFilter} GROUP BY sd.id, sd.name, d.name ORDER BY total_amount DESC `, queryParams, ); // Get summary by activity type const byActivity = await db.query( ` SELECT COALESCE(wa.activity, 'Standard') as activity, COUNT(*) as total_allocations, SUM(COALESCE(wa.total_amount, wa.rate, 0)) as total_amount, SUM(COALESCE(wa.units, 0)) as total_units FROM work_allocations wa JOIN users e ON wa.employee_id = e.id WHERE wa.status = 'Completed' ${departmentFilter} ${dateFilter} GROUP BY wa.activity ORDER BY total_amount DESC `, queryParams, ); ctx.response.body = { byContractor, bySubDepartment, byActivity, }; } catch (error) { console.error("Get report summary error:", error); ctx.response.status = 500; ctx.response.body = { error: "Internal server error" }; } }, ); export default router;