resolveBusiness($request); if (! $business) { return $this->jsonError('کسب‌وکار یافت نشد.', 404); } $query = FailureReport::where('business_id', $business->id) ->with(['equipment:id,name,code', 'project:id,name', 'productionLine:id,name,code', 'reporter:id,name']) ->orderByDesc('reported_at'); $this->applyMaintenanceScopeFilters($query, $request); if ($equipmentId = $request->get('equipment_id')) { $query->where('equipment_id', $equipmentId); } $paginator = $query->paginate((int) $request->get('per_page', 15)); return $this->jsonSuccess([ 'items' => $paginator->items(), 'pagination' => [ 'total' => $paginator->total(), 'per_page' => $paginator->perPage(), 'current_page' => $paginator->currentPage(), 'last_page' => $paginator->lastPage(), ], ]); } public function store(Request $request) { $business = $this->resolveBusiness($request); if (! $business) { return $this->jsonError('کسب‌وکار یافت نشد.', 404); } $data = $request->validate(array_merge([ 'work_order_id' => ['nullable', 'exists:maintenance_work_orders,id'], 'failure_type' => ['nullable', 'string'], 'root_cause' => ['nullable', 'string'], 'corrective_action' => ['nullable', 'string'], 'preventive_action' => ['nullable', 'string'], 'downtime_hours' => ['sometimes', 'numeric', 'min:0'], 'repair_hours' => ['sometimes', 'numeric', 'min:0'], 'lost_production' => ['nullable', 'numeric'], 'cost' => ['sometimes', 'integer', 'min:0'], ], $this->equipmentIdsValidationRules(), $this->scopeValidationRules())); $equipmentIds = $this->resolveEquipmentIds($data); if (empty($equipmentIds)) { return $this->jsonError('حداقل یک تجهیز انتخاب کنید.', 422); } unset($data['equipment_id'], $data['equipment_ids']); try { $data = $this->syncScopeFromLine($data); } catch (\InvalidArgumentException $e) { return $this->jsonError($e->getMessage(), 422); } $created = []; foreach ($equipmentIds as $equipmentId) { $report = FailureReport::create(array_merge($data, [ 'business_id' => $business->id, 'equipment_id' => $equipmentId, 'reported_by' => $request->user()?->id, 'reported_at' => now(), ])); MaintenanceActivityService::logEquipmentHistory( $business, $report->equipment_id, 'repair', 'گزارش خرابی', $report->failure_type, $request->user(), (int) ($report->cost ?? 0), FailureReport::class, $report->id ); $created[] = $report->load('equipment'); } $message = count($created) > 1 ? count($created).' گزارش خرابی برای تجهیزات انتخاب‌شده ثبت شد.' : 'گزارش خرابی ثبت شد.'; return $this->jsonSuccess( count($created) === 1 ? $created[0] : ['items' => $created, 'count' => count($created)], $message, 201 ); } public function update(Request $request, FailureReport $failureReport) { if (! $this->ensureBusinessOwnership($request, $failureReport->business_id)) { return $this->jsonError('دسترسی ندارید.', 403); } $data = $request->validate(array_merge([ 'failure_type' => ['nullable', 'string'], 'root_cause' => ['nullable', 'string'], 'corrective_action' => ['nullable', 'string'], 'preventive_action' => ['nullable', 'string'], 'downtime_hours' => ['sometimes', 'numeric', 'min:0'], 'repair_hours' => ['sometimes', 'numeric', 'min:0'], 'lost_production' => ['nullable', 'numeric'], 'cost' => ['sometimes', 'integer', 'min:0'], ], $this->scopeValidationRules())); try { $data = $this->syncScopeFromLine(array_merge([ 'project_id' => $failureReport->project_id, 'production_line_id' => $failureReport->production_line_id, ], $data)); } catch (\InvalidArgumentException $e) { return $this->jsonError($e->getMessage(), 422); } $failureReport->update($data); return $this->jsonSuccess($failureReport, 'گزارش به‌روزرسانی شد.'); } public function destroy(Request $request, FailureReport $failureReport) { if (! $this->ensureBusinessOwnership($request, $failureReport->business_id)) { return $this->jsonError('دسترسی ندارید.', 403); } $failureReport->delete(); return $this->jsonSuccess(null, 'گزارش حذف شد.'); } }