resolveBusiness($request); if (! $business) { return $this->jsonError('کسب‌وکار یافت نشد.', 404); } $query = WorkOrder::where('business_id', $business->id) ->with(['equipment:id,name,code', 'project:id,name', 'productionLine:id,name,code', 'assignedTechnician:id,name', 'requester:id,name']) ->orderByDesc('created_at'); $this->applyMaintenanceScopeFilters($query, $request); if ($status = $request->get('status')) { $query->where('status', $status); } if ($equipmentId = $request->get('equipment_id')) { $query->where('equipment_id', $equipmentId); } if ($technicianId = $request->get('technician_id')) { $query->where('assigned_technician_id', $technicianId); } $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([ 'description' => ['nullable', 'string'], 'priority' => ['sometimes', 'string', 'in:low,medium,high,urgent'], 'assigned_technician_id' => ['nullable', 'exists:users,id'], 'preventive_schedule_id' => ['nullable', 'exists:maintenance_preventive_schedules,id'], 'overhaul_id' => ['nullable', 'exists:maintenance_overhauls,id'], 'scheduled_at' => ['nullable', 'date'], 'status' => ['sometimes', 'string', 'in:draft,open,in_progress,on_hold,completed,cancelled'], ], $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) { $workOrder = WorkOrder::create(array_merge($data, [ 'business_id' => $business->id, 'equipment_id' => $equipmentId, 'work_order_number' => $this->workOrderService->generateNumber($business), 'requester_id' => $request->user()?->id, 'status' => $data['status'] ?? 'open', ])); MaintenanceActivityService::log( $business, 'created', 'work_order', $workOrder->id, "دستور کار {$workOrder->work_order_number} ایجاد شد.", $request->user() ); $created[] = $workOrder->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 show(Request $request, WorkOrder $workOrder) { if (! $this->ensureBusinessOwnership($request, $workOrder->business_id)) { return $this->jsonError('دسترسی ندارید.', 403); } return $this->jsonSuccess($workOrder->load([ 'equipment', 'assignedTechnician', 'requester', 'parts.sparePart', ])); } public function update(Request $request, WorkOrder $workOrder) { if (! $this->ensureBusinessOwnership($request, $workOrder->business_id)) { return $this->jsonError('دسترسی ندارید.', 403); } $data = $request->validate(array_merge([ 'description' => ['nullable', 'string'], 'priority' => ['sometimes', 'string', 'in:low,medium,high,urgent'], 'assigned_technician_id' => ['nullable', 'exists:users,id'], 'status' => ['sometimes', 'string', 'in:draft,open,in_progress,on_hold,completed,cancelled'], 'labor_hours' => ['nullable', 'numeric'], 'completion_report' => ['nullable', 'string'], 'scheduled_at' => ['nullable', 'date'], 'images' => ['nullable', 'array'], 'attachments' => ['nullable', 'array'], 'signature' => ['nullable', 'array'], ], $this->scopeValidationRules())); try { $data = $this->syncScopeFromLine(array_merge([ 'project_id' => $workOrder->project_id, 'production_line_id' => $workOrder->production_line_id, ], $data)); } catch (\InvalidArgumentException $e) { return $this->jsonError($e->getMessage(), 422); } if (($data['status'] ?? null) === 'completed' && ! $workOrder->completed_at) { $data['completed_at'] = now(); } $workOrder->update($data); return $this->jsonSuccess($workOrder->fresh()->load('equipment'), 'دستور کار به‌روزرسانی شد.'); } public function consumePart(Request $request, WorkOrder $workOrder) { $business = $this->resolveBusiness($request); if (! $business || $workOrder->business_id !== $business->id) { return $this->jsonError('دسترسی ندارید.', 403); } $data = $request->validate([ 'spare_part_id' => ['required', 'exists:maintenance_spare_parts,id'], 'quantity' => ['required', 'numeric', 'min:0.001'], ]); try { $consumption = $this->sparePartService->consumeForWorkOrder( $business, $workOrder, $data['spare_part_id'], (float) $data['quantity'], $request->user() ); } catch (\InvalidArgumentException $e) { return $this->jsonError($e->getMessage(), 422); } return $this->jsonSuccess($consumption->load('sparePart'), 'قطعه مصرف شد.'); } public function destroy(Request $request, WorkOrder $workOrder) { if (! $this->ensureBusinessOwnership($request, $workOrder->business_id)) { return $this->jsonError('دسترسی ندارید.', 403); } $workOrder->delete(); return $this->jsonSuccess(null, 'دستور کار حذف شد.'); } }