authorizeMaintenanceAccess('maintenance.equipment.view'); $business_id = $this->maintenanceUtil->getBusinessId(); if ($request->ajax()) { $query = Equipment::where('business_id', $business_id) ->with(['category:id,name', 'project:id,name', 'productionLine:id,name,code', 'customer:id,name']) ->orderByDesc('created_at'); if ($status = $request->get('status')) { $query->where('status', $status); } if ($category_id = $request->get('category_id')) { $query->where('category_id', $category_id); } if ($project_id = $request->get('project_id')) { $query->where('project_id', $project_id); } if ($production_line_id = $request->get('production_line_id')) { $query->where('production_line_id', $production_line_id); } return DataTables::of($query) ->addColumn('category_name', fn ($row) => $row->category?->name ?? '—') ->addColumn('project_name', fn ($row) => $row->project?->name ?? '—') ->addColumn('line_name', fn ($row) => $row->productionLine?->name ?? '—') ->addColumn('status_label', fn ($row) => $this->maintenanceUtil->statusLabel($row->status)) ->addColumn('priority_label', fn ($row) => $this->maintenanceUtil->priorityLabel($row->priority)) ->addColumn('action', function ($row) { $html = '
'; return $html; }) ->editColumn('health_percentage', fn ($row) => $row->health_percentage !== null ? number_format((float) $row->health_percentage, 1).'%' : '—') ->rawColumns(['action']) ->make(true); } return view('maintenance::equipment.index', [ 'categories' => $this->maintenanceUtil->getCategoriesDropdown($business_id), 'projects' => $this->maintenanceUtil->getProjectsDropdown($business_id), 'production_lines' => $this->maintenanceUtil->getProductionLinesDropdown($business_id), 'statuses' => $this->maintenanceUtil->statusLabels(), ]); } public function create() { $this->authorizeMaintenanceAccess('maintenance.equipment.create'); $business_id = $this->maintenanceUtil->getBusinessId(); return view('maintenance::equipment.create', [ 'categories' => $this->maintenanceUtil->getCategoriesDropdown($business_id), 'projects' => $this->maintenanceUtil->getProjectsDropdown($business_id), 'production_lines' => $this->maintenanceUtil->getProductionLinesDropdown( $business_id, request()->get('project_id') ), 'customers' => $this->maintenanceUtil->getCustomersDropdown($business_id), 'assets' => $this->maintenanceUtil->getAssetsDropdown( $business_id, request()->get('project_id') ), 'statuses' => $this->maintenanceUtil->statusLabels(), 'priorities' => $this->maintenanceUtil->priorityLabels(), 'prefill_customer_id' => request()->get('customer_id'), 'prefill_project_id' => request()->get('project_id'), 'prefill_client_type' => request()->get('client_type', 'factory'), ]); } public function store(Request $request) { $this->authorizeMaintenanceAccess('maintenance.equipment.create'); $business_id = $this->maintenanceUtil->getBusinessId(); $business = $this->maintenanceUtil->getBusiness(); $data = $request->validate([ 'code' => 'required|string|max:50', 'name' => 'required|string|max:255', 'category_id' => 'nullable|exists:maintenance_equipment_categories,id', 'project_id' => 'required|exists:pjt_projects,id', 'production_line_id' => 'required|exists:maintenance_production_lines,id', 'client_type' => 'required|in:person,factory,project', 'customer_id' => 'nullable|required_if:client_type,person,factory|exists:contacts,id', 'asset_number' => 'nullable|string|max:255', 'manufacturer' => 'nullable|string|max:255', 'model' => 'nullable|string|max:255', 'serial_number' => 'nullable|string|max:255', 'capacity' => 'nullable|string|max:255', 'installation_date' => 'nullable|string', 'warranty_expires_at' => 'nullable|string', 'location' => 'nullable|string|max:255', 'status' => 'sometimes|in:active,inactive,under_maintenance,under_overhaul,retired', 'priority' => 'sometimes|in:low,medium,high,critical', 'criticality' => 'sometimes|in:low,medium,high', 'risk_level' => 'sometimes|in:low,medium,high,critical', 'working_hours' => 'nullable|numeric', 'health_percentage' => 'nullable|numeric|min:0|max:100', 'fixed_asset_id' => 'nullable|integer|exists:assets,id', 'notes' => 'nullable|string', ]); try { $data = $this->syncScopeFromLine($data); } catch (\InvalidArgumentException $e) { return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage()); } if ($data['client_type'] === 'project') { $data['customer_id'] = null; } $data['installation_date'] = $this->maintenanceUtil->parseInputDate($data['installation_date'] ?? null); $data['warranty_expires_at'] = $this->maintenanceUtil->parseInputDate($data['warranty_expires_at'] ?? null); $equipment = new Equipment(array_merge($data, [ 'business_id' => $business_id, 'created_by' => auth()->id(), 'status' => $data['status'] ?? 'active', ])); $equipment = $this->crmSyncService->syncCustomerFromProject($equipment); $equipment->save(); $assetId = $this->assetSyncService->syncAssetForEquipment($equipment, $business_id, (int) auth()->id()); if ($assetId) { $equipment->update(['fixed_asset_id' => $assetId]); } $this->preventiveService->generateEquipmentQrCode($business, $equipment); MaintenanceActivityService::log( $business, 'created', 'equipment', $equipment->id, "تجهیز «{$equipment->name}» ایجاد شد.", auth()->user() ); $this->crmSyncService->notifyCrmOnEquipmentCreated($equipment, auth()->user()); return $this->maintenanceUtil->jsonOrRedirect( $request, true, 'تجهیز با موفقیت ثبت شد.', action([self::class, 'show'], [$equipment->id]) ); } public function show($id) { $this->authorizeMaintenanceAccess('maintenance.equipment.view'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id) ->with(MaintenanceSchema::equipmentShowRelations()) ->findOrFail($id); $partsTree = $this->maintenanceUtil->buildEquipmentPartsTree($equipment->equipmentParts); return view('maintenance::equipment.show', compact('equipment', 'partsTree')); } public function edit($id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($id); return view('maintenance::equipment.edit', [ 'equipment' => $equipment, 'categories' => $this->maintenanceUtil->getCategoriesDropdown($business_id), 'projects' => $this->maintenanceUtil->getProjectsDropdown($business_id), 'production_lines' => $this->maintenanceUtil->getProductionLinesDropdown($business_id, $equipment->project_id), 'customers' => $this->maintenanceUtil->getCustomersDropdown($business_id), 'assets' => $this->maintenanceUtil->getAssetsDropdown($business_id, $equipment->project_id), 'statuses' => $this->maintenanceUtil->statusLabels(), 'priorities' => $this->maintenanceUtil->priorityLabels(), ]); } public function update(Request $request, $id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $business = $this->maintenanceUtil->getBusiness(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($id); $data = $request->validate([ 'code' => 'sometimes|string|max:50', 'name' => 'sometimes|string|max:255', 'category_id' => 'nullable|exists:maintenance_equipment_categories,id', 'project_id' => 'sometimes|required|exists:pjt_projects,id', 'production_line_id' => 'sometimes|required|exists:maintenance_production_lines,id', 'client_type' => 'sometimes|in:person,factory,project', 'customer_id' => 'nullable|exists:contacts,id', 'asset_number' => 'nullable|string|max:255', 'manufacturer' => 'nullable|string|max:255', 'model' => 'nullable|string|max:255', 'serial_number' => 'nullable|string|max:255', 'capacity' => 'nullable|string|max:255', 'installation_date' => 'nullable|string', 'warranty_expires_at' => 'nullable|string', 'location' => 'nullable|string|max:255', 'status' => 'sometimes|in:active,inactive,under_maintenance,under_overhaul,retired', 'priority' => 'sometimes|in:low,medium,high,critical', 'criticality' => 'sometimes|in:low,medium,high', 'risk_level' => 'sometimes|in:low,medium,high,critical', 'working_hours' => 'nullable|numeric', 'health_percentage' => 'nullable|numeric|min:0|max:100', 'fixed_asset_id' => 'nullable|integer|exists:assets,id', 'notes' => 'nullable|string', ]); if (isset($data['production_line_id']) || isset($data['project_id'])) { $merged = array_merge([ 'project_id' => $equipment->project_id, 'production_line_id' => $equipment->production_line_id, ], $data); try { $data = array_merge($data, $this->syncScopeFromLine($merged)); } catch (\InvalidArgumentException $e) { return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage()); } } if (($data['client_type'] ?? $equipment->client_type) === 'project') { $data['customer_id'] = null; } if (array_key_exists('installation_date', $data)) { $data['installation_date'] = $this->maintenanceUtil->parseInputDate($data['installation_date']); } if (array_key_exists('warranty_expires_at', $data)) { $data['warranty_expires_at'] = $this->maintenanceUtil->parseInputDate($data['warranty_expires_at']); } $equipment->fill($data); $equipment = $this->crmSyncService->syncCustomerFromProject($equipment); $equipment->updated_by = auth()->id(); $equipment->save(); if (empty($equipment->fixed_asset_id)) { $assetId = $this->assetSyncService->syncAssetForEquipment($equipment, $business_id, (int) auth()->id()); if ($assetId) { $equipment->update(['fixed_asset_id' => $assetId]); } } else { $this->assetSyncService->updateLinkedAsset($equipment->fresh()); } MaintenanceActivityService::log( $business, 'updated', 'equipment', $equipment->id, "تجهیز «{$equipment->name}» ویرایش شد.", auth()->user() ); return $this->maintenanceUtil->jsonOrRedirect( $request, true, 'تجهیز بهروزرسانی شد.', action([self::class, 'show'], [$equipment->id]) ); } public function destroy(Request $request, $id) { $this->authorizeMaintenanceAccess('maintenance.equipment.delete'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($id); $equipment->delete(); return $this->maintenanceUtil->jsonOrRedirect($request, true, 'تجهیز حذف شد.', action([self::class, 'index'])); } public function assetsDropdown(Request $request) { $this->authorizeMaintenanceAccess('maintenance.equipment.view'); $business_id = $this->maintenanceUtil->getBusinessId(); $project_id = $request->get('project_id'); return response()->json( $this->maintenanceUtil->getAssetsDropdown($business_id, $project_id ?: null) ); } }