110%) */ class UtilizationController extends Controller { use AuthorizesRequests; public function __construct( private UtilizationService $utilizationService ) {} /** * Get Running (YTD) Utilization * * Calculate year-to-date utilization for a specific team member. * Running utilization = (Allocated hours Jan-current) / (Capacity Jan-current) × 100% * * @authenticated * * @queryParam team_member_id string required UUID of the team member. Example: 550e8400-e29b-41d4-a716-446655440000 * @queryParam month string required Month in Y-m format (calculates from Jan of this year to this month). Example: 2026-03 * * @response 200 { * "capacity_ytd": 480.0, * "allocated_ytd": 450.0, * "utilization": 93.8, * "indicator": "green", * "months_included": 3 * } * @response 422 {"message":"Validation failed","errors":{"team_member_id":["The selected team member id is invalid."]}} */ public function running(Request $request): JsonResponse { $this->authorize('viewRunningUtilization', \App\Models\TeamMember::class); $request->validate([ 'team_member_id' => 'required|uuid|exists:team_members,id', 'month' => 'required|date_format:Y-m', ]); $result = $this->utilizationService->calculateRunningUtilization( $request->team_member_id, $request->month ); return response()->json($result); } /** * Get Overall (Monthly) Utilization * * Calculate utilization for a specific team member in a specific month. * Overall utilization = (Allocated hours this month) / (Capacity this month) × 100% * * @authenticated * * @queryParam team_member_id string required UUID of the team member. Example: 550e8400-e29b-41d4-a716-446655440000 * @queryParam month string required Month in Y-m format. Example: 2026-02 * * @response 200 { * "capacity": 160.0, * "allocated": 140.0, * "utilization": 87.5, * "indicator": "green" * } * @response 422 {"message":"Validation failed","errors":{"month":["The month format is invalid."]}} */ public function overall(Request $request): JsonResponse { $this->authorize('viewOverallUtilization', \App\Models\TeamMember::class); $request->validate([ 'team_member_id' => 'required|uuid|exists:team_members,id', 'month' => 'required|date_format:Y-m', ]); $result = $this->utilizationService->calculateOverallUtilization( $request->team_member_id, $request->month ); return response()->json($result); } /** * Get Combined Utilization Data * * Get both overall (monthly) and running (YTD) utilization for a team member. * * @authenticated * * @queryParam team_member_id string required UUID of the team member. Example: 550e8400-e29b-41d4-a716-446655440000 * @queryParam month string required Month in Y-m format. Example: 2026-03 * * @response 200 { * "overall": { * "capacity": 160.0, * "allocated": 140.0, * "utilization": 87.5, * "indicator": "green" * }, * "running": { * "capacity_ytd": 480.0, * "allocated_ytd": 450.0, * "utilization": 93.8, * "indicator": "green", * "months_included": 3 * } * } */ public function data(Request $request): JsonResponse { $this->authorize('viewUtilization', \App\Models\TeamMember::class); $request->validate([ 'team_member_id' => 'required|uuid|exists:team_members,id', 'month' => 'required|date_format:Y-m', ]); $result = $this->utilizationService->getUtilizationData( $request->team_member_id, $request->month ); return response()->json($result); } /** * Get Team Utilization * * Calculate average utilization across all active team members for a specific month. * * @authenticated * * @queryParam month string required Month in Y-m format. Example: 2026-02 * * @response 200 { * "average_utilization": 85.4, * "average_indicator": "green", * "member_count": 3, * "by_member": { * "550e8400-e29b-41d4-a716-446655440000": { * "capacity": 160.0, * "allocated": 140.0, * "utilization": 87.5, * "indicator": "green" * } * } * } */ public function team(Request $request): JsonResponse { $this->authorize('viewTeamUtilization', \App\Models\TeamMember::class); $request->validate([ 'month' => 'required|date_format:Y-m', ]); $result = $this->utilizationService->calculateTeamUtilization( $request->month ); return response()->json($result); } /** * Get Team Running Utilization (YTD) * * Calculate average year-to-date utilization across all active team members. * * @authenticated * * @queryParam month string required Month in Y-m format. Example: 2026-03 * * @response 200 { * "average_utilization": 88.2, * "average_indicator": "green", * "member_count": 3, * "by_member": {} * } */ public function teamRunning(Request $request): JsonResponse { $this->authorize('viewTeamRunningUtilization', \App\Models\TeamMember::class); $request->validate([ 'month' => 'required|date_format:Y-m', ]); $result = $this->utilizationService->calculateTeamRunningUtilization( $request->month ); return response()->json($result); } /** * Get Utilization Trend * * Get utilization data for a team member over a range of months. * * @authenticated * * @queryParam team_member_id string required UUID of the team member. Example: 550e8400-e29b-41d4-a716-446655440000 * @queryParam start_month string required Start month in Y-m format. Example: 2026-01 * @queryParam end_month string required End month in Y-m format (must be >= start_month). Example: 2026-06 * * @response 200 [ * { * "month": "2026-01", * "utilization": 75.0, * "indicator": "blue", * "capacity": 176.0, * "allocated": 132.0 * }, * { * "month": "2026-02", * "utilization": 87.5, * "indicator": "green", * "capacity": 160.0, * "allocated": 140.0 * } * ] */ public function trend(Request $request): JsonResponse { $this->authorize('viewUtilizationTrend', \App\Models\TeamMember::class); $request->validate([ 'team_member_id' => 'required|uuid|exists:team_members,id', 'start_month' => 'required|date_format:Y-m', 'end_month' => 'required|date_format:Y-m|after_or_equal:start_month', ]); $result = $this->utilizationService->getUtilizationTrend( $request->team_member_id, $request->start_month, $request->end_month ); return response()->json($result); } }