authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($equipment_id); return view('maintenance::equipment_parts.create', [ 'equipment' => $equipment, 'parent_parts' => $this->maintenanceUtil->getEquipmentPartsDropdown($equipment->id), 'part_catalogs' => $this->maintenanceUtil->getPartCatalogsDropdown($business_id), 'spare_parts' => $this->maintenanceUtil->getSparePartsDropdown($business_id), 'part_types' => $this->maintenanceUtil->partTypeLabels(), 'warranty_statuses' => $this->maintenanceUtil->warrantyStatusLabels(), ]); } public function store(Request $request, $equipment_id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($equipment_id); $data = $this->validatePart($request); $data = $this->enrichFromCatalogOrSpare($data); if (! empty($data['warranty_expires_at'])) { $data['warranty_expires_at'] = $this->maintenanceUtil->parseInputDate($data['warranty_expires_at']); } if (! empty($data['expected_replacement_date'])) { $data['expected_replacement_date'] = $this->maintenanceUtil->parseInputDate($data['expected_replacement_date']); } EquipmentPart::create(array_merge($data, [ 'business_id' => $business_id, 'equipment_id' => $equipment->id, 'quantity' => $data['quantity'] ?? 1, 'is_consumable' => $request->boolean('is_consumable'), 'is_critical' => $request->boolean('is_critical'), ])); return $this->maintenanceUtil->jsonOrRedirect( $request, true, 'قطعه به تجهیز اضافه شد.', action([EquipmentController::class, 'show'], [$equipment->id]).'#tab_parts' ); } public function edit($equipment_id, $id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($equipment_id); $part = EquipmentPart::where('equipment_id', $equipment->id)->findOrFail($id); return view('maintenance::equipment_parts.edit', [ 'equipment' => $equipment, 'part' => $part, 'parent_parts' => $this->maintenanceUtil->getEquipmentPartsDropdown($equipment->id, $part->id), 'part_catalogs' => $this->maintenanceUtil->getPartCatalogsDropdown($business_id), 'spare_parts' => $this->maintenanceUtil->getSparePartsDropdown($business_id), 'part_types' => $this->maintenanceUtil->partTypeLabels(), 'warranty_statuses' => $this->maintenanceUtil->warrantyStatusLabels(), ]); } public function update(Request $request, $equipment_id, $id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($equipment_id); $part = EquipmentPart::where('equipment_id', $equipment->id)->findOrFail($id); $data = $this->validatePart($request, true); if (isset($data['parent_id']) && (int) $data['parent_id'] === (int) $part->id) { return $this->maintenanceUtil->jsonOrRedirect($request, false, 'قطعه نمی‌تواند والد خودش باشد.'); } $data = $this->enrichFromCatalogOrSpare($data); $data['is_consumable'] = $request->boolean('is_consumable'); $data['is_critical'] = $request->boolean('is_critical'); if (array_key_exists('warranty_expires_at', $data)) { $data['warranty_expires_at'] = $this->maintenanceUtil->parseInputDate($data['warranty_expires_at']); } if (array_key_exists('expected_replacement_date', $data)) { $data['expected_replacement_date'] = $this->maintenanceUtil->parseInputDate($data['expected_replacement_date']); } $part->update($data); return $this->maintenanceUtil->jsonOrRedirect( $request, true, 'قطعه به‌روزرسانی شد.', action([EquipmentController::class, 'show'], [$equipment->id]).'#tab_parts' ); } public function destroy(Request $request, $equipment_id, $id) { $this->authorizeMaintenanceAccess('maintenance.equipment.update'); $business_id = $this->maintenanceUtil->getBusinessId(); $equipment = Equipment::where('business_id', $business_id)->findOrFail($equipment_id); $part = EquipmentPart::where('equipment_id', $equipment->id)->findOrFail($id); $part->delete(); if ($request->ajax() || $request->wantsJson()) { return response()->json(['success' => true, 'msg' => 'قطعه حذف شد.']); } return $this->maintenanceUtil->jsonOrRedirect( $request, true, 'قطعه حذف شد.', action([EquipmentController::class, 'show'], [$equipment->id]).'#tab_parts' ); } private function validatePart(Request $request, bool $partial = false): array { $required = $partial ? 'sometimes' : 'nullable'; return $request->validate([ 'parent_id' => [$required, 'nullable', 'exists:maintenance_equipment_parts,id'], 'spare_part_id' => ['nullable', 'exists:maintenance_spare_parts,id'], 'part_catalog_id' => ['nullable', 'exists:maintenance_part_catalogs,id'], 'part_name' => [$partial ? 'sometimes' : 'required_without:spare_part_id', 'nullable', 'string', 'max:255'], 'part_code' => ['nullable', 'string', 'max:100'], 'quantity' => ['nullable', 'numeric', 'min:0'], 'unit' => ['nullable', 'string', 'max:50'], 'part_type' => ['sometimes', 'string', 'in:mechanical,electronic,consumable,hydraulic,pneumatic'], 'responsibility' => ['sometimes', 'string', 'in:ours,vendor,shared'], 'responsibility_party_name' => ['nullable', 'string', 'max:255'], 'warranty_status' => ['sometimes', 'string', 'in:none,active,expired'], 'warranty_provider' => ['nullable', 'string', 'max:255'], 'warranty_expires_at' => ['nullable', 'string'], 'expected_replacement_date' => ['nullable', 'string'], 'replacement_interval_days' => ['nullable', 'integer', 'min:0'], 'health_percentage' => ['nullable', 'numeric', 'min:0', 'max:100'], 'notes' => ['nullable', 'string'], ]); } private function enrichFromCatalogOrSpare(array $data): array { if (! empty($data['spare_part_id'])) { $spare = SparePart::find($data['spare_part_id']); if ($spare) { $data['part_name'] = $data['part_name'] ?? $spare->name; $data['part_code'] = $data['part_code'] ?? $spare->part_number; $data['unit'] = $data['unit'] ?? $spare->unit; } } if (! empty($data['part_catalog_id'])) { $catalog = PartCatalog::find($data['part_catalog_id']); if ($catalog) { $data['part_name'] = $data['part_name'] ?? $catalog->name; $data['part_code'] = $data['part_code'] ?? $catalog->catalog_code; $data['part_type'] = $data['part_type'] ?? $catalog->part_type; $data['is_consumable'] = $data['is_consumable'] ?? $catalog->is_consumable; } } return $data; } }