id) ->where('status', 'completed') ->with('equipment:id,name,code'); if ($equipmentId) { $query->where('equipment_id', $equipmentId); } return $query->get() ->groupBy('equipment_id') ->map(fn ($orders, $eqId) => [ 'equipment_id' => (int) $eqId, 'equipment' => $orders->first()->equipment, 'total_cost' => (int) $orders->sum('cost'), 'work_order_count' => $orders->count(), ]) ->values(); } public function downtimeReport(Business $business, ?string $from = null, ?string $to = null): Collection { $query = FailureReport::where('business_id', $business->id)->with('equipment:id,name,code'); if ($from) { $query->where('reported_at', '>=', $from); } if ($to) { $query->where('reported_at', '<=', $to); } return $query->get()->map(fn ($r) => [ 'equipment' => $r->equipment, 'failure_type' => $r->failure_type, 'downtime_hours' => (float) $r->downtime_hours, 'repair_hours' => (float) $r->repair_hours, 'cost' => (int) $r->cost, 'reported_at' => $r->reported_at?->toDateTimeString(), ]); } public function technicianPerformance(Business $business): Collection { return WorkOrder::where('business_id', $business->id) ->where('status', 'completed') ->whereNotNull('assigned_technician_id') ->with('assignedTechnician:id,name') ->get() ->groupBy('assigned_technician_id') ->map(fn ($orders, $techId) => [ 'technician_id' => (int) $techId, 'technician' => $orders->first()->assignedTechnician, 'completed_count' => $orders->count(), 'total_labor_hours' => (float) $orders->sum('labor_hours'), 'total_cost' => (int) $orders->sum('cost'), ]) ->values(); } public function sparePartsConsumption(Business $business, ?string $from = null, ?string $to = null): Collection { $query = SparePartConsumption::where('business_id', $business->id) ->with(['sparePart:id,part_number,name', 'equipment:id,name']); if ($from) { $query->where('created_at', '>=', $from); } if ($to) { $query->where('created_at', '<=', $to); } return $query->orderByDesc('created_at')->get(); } public function monthlyStatistics(Business $business, int $year, int $month): array { $start = Carbon::create($year, $month, 1)->startOfMonth(); $end = $start->copy()->endOfMonth(); $bid = $business->id; return [ 'period' => $start->format('Y-m'), 'work_orders_completed' => WorkOrder::where('business_id', $bid) ->where('status', 'completed') ->whereBetween('completed_at', [$start, $end]) ->count(), 'overhauls_completed' => Overhaul::where('business_id', $bid) ->where('status', 'completed') ->whereBetween('updated_at', [$start, $end]) ->count(), 'failures' => FailureReport::where('business_id', $bid) ->whereBetween('reported_at', [$start, $end]) ->count(), 'total_cost' => (int) WorkOrder::where('business_id', $bid) ->where('status', 'completed') ->whereBetween('completed_at', [$start, $end]) ->sum('cost'), 'total_downtime_hours' => (float) FailureReport::where('business_id', $bid) ->whereBetween('reported_at', [$start, $end]) ->sum('downtime_hours'), ]; } public function failureAnalysis(Business $business): Collection { return FailureReport::where('business_id', $business->id) ->selectRaw('failure_type, count(*) as count, sum(downtime_hours) as total_downtime, sum(cost) as total_cost') ->groupBy('failure_type') ->get(); } }