authorizeMaintenanceAccess('maintenance.repair_dispatch.view'); $business_id = $this->maintenanceUtil->getBusinessId(); if ($request->ajax()) { $query = RepairDispatch::where('business_id', $business_id) ->with(['materialLine.sparePart', 'holdingEntity', 'orgUnit', 'serviceProvider']) ->orderByDesc('id'); if ($status = $request->get('status')) { $query->where('status', $status); } if ($route = $request->get('route_type')) { $query->where('route_type', $route); } $statusLabels = $this->dispatchService->statusLabels(); $routeLabels = $this->dispatchService->routeTypeLabels(); return DataTables::of($query) ->addColumn('part_name', fn ($row) => $row->materialLine?->displayName() ?? '—') ->addColumn('destination', fn ($row) => $row->destinationLabel()) ->addColumn('route_label', fn ($row) => $routeLabels[$row->route_type] ?? $row->route_type) ->addColumn('status_label', fn ($row) => $statusLabels[$row->status] ?? $row->status) ->addColumn('action', function ($row) { return ''; }) ->editColumn('sent_at', fn ($row) => $this->maintenanceUtil->formatDateTime($row->sent_at)) ->editColumn('expected_return_at', fn ($row) => $this->maintenanceUtil->formatDate($row->expected_return_at)) ->rawColumns(['action']) ->make(true); } return view('maintenance::repair_dispatches.index', [ 'statuses' => $this->dispatchService->statusLabels(), 'route_types' => $this->dispatchService->routeTypeLabels(), ]); } public function show($id) { $this->authorizeMaintenanceAccess('maintenance.repair_dispatch.view'); $business_id = $this->maintenanceUtil->getBusinessId(); $dispatch = RepairDispatch::where('business_id', $business_id) ->with(['materialLine.sparePart', 'materialList', 'holdingEntity', 'orgUnit', 'serviceProvider', 'originLocation', 'events.user']) ->findOrFail($id); return view('maintenance::repair_dispatches.show', [ 'dispatch' => $dispatch, 'statuses' => $this->dispatchService->statusLabels(), 'route_types' => $this->dispatchService->routeTypeLabels(), 'next_action' => $this->dispatchService->nextActionLabel($dispatch), 'can_manage' => auth()->user()->can('maintenance.repair_dispatch.manage'), ]); } public function store(Request $request, int $lineId) { $this->authorizeMaintenanceAccess('maintenance.repair_dispatch.manage'); $business = $this->maintenanceUtil->getBusiness(); $line = MaterialLine::where('business_id', $business->id) ->with('materialList') ->findOrFail($lineId); $data = $request->validate([ 'route_type' => 'required|in:internal,external', 'holding_entity_id' => 'nullable|integer|exists:holding_entities,id', 'org_unit_id' => 'nullable|integer|exists:org_units,id', 'service_provider_id' => 'nullable|integer|exists:maintenance_service_providers,id', 'external_party_name' => 'nullable|string|max:255', 'external_address' => 'nullable|string', 'origin_location_id' => 'nullable|integer|exists:business_locations,id', 'quantity' => 'nullable|numeric|min:0.001', 'expected_return_at' => 'nullable|string', 'send_notes' => 'nullable|string', 'tracking_number_out' => 'nullable|string|max:100', 'carrier' => 'nullable|string|max:100', ]); if (! empty($data['expected_return_at'])) { $data['expected_return_at'] = $this->maintenanceUtil->parseInputDate($data['expected_return_at']); } try { $dispatch = $this->dispatchService->createDispatch($line->materialList, $line, $data, auth()->user()); } catch (\InvalidArgumentException $e) { return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->maintenanceUtil->jsonOrRedirect( $request, true, __('maintenance::lang.rd_created', ['ref' => $dispatch->dispatch_number]), action([self::class, 'show'], [$dispatch->id]) ); } public function advance(Request $request, $id) { $this->authorizeMaintenanceAccess('maintenance.repair_dispatch.manage'); $business_id = $this->maintenanceUtil->getBusinessId(); $dispatch = RepairDispatch::where('business_id', $business_id)->findOrFail($id); $data = $request->validate([ 'notes' => 'nullable|string', 'repair_report' => 'nullable|string', 'repair_cost' => 'nullable|integer|min:0', 'tracking_number_return' => 'nullable|string|max:100', 'receive_notes' => 'nullable|string', ]); try { $this->dispatchService->advanceStatus($dispatch, $data['notes'] ?? null, $data, auth()->user()); } catch (\InvalidArgumentException $e) { return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->maintenanceUtil->jsonOrRedirect($request, true, __('maintenance::lang.rd_status_updated')); } public function cancel(Request $request, $id) { $this->authorizeMaintenanceAccess('maintenance.repair_dispatch.manage'); $business_id = $this->maintenanceUtil->getBusinessId(); $dispatch = RepairDispatch::where('business_id', $business_id)->findOrFail($id); $data = $request->validate(['notes' => 'nullable|string']); try { $this->dispatchService->cancel($dispatch, $data['notes'] ?? null, auth()->user()); } catch (\InvalidArgumentException $e) { return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage()); } return $this->maintenanceUtil->jsonOrRedirect($request, true, __('maintenance::lang.rd_cancelled')); } public function orgUnits(Request $request) { $business_id = $this->maintenanceUtil->getBusinessId(); $entityId = $request->get('entity_id'); return response()->json([ 'success' => true, 'data' => $this->maintenanceUtil->getOrgUnitsDropdown($business_id, $entityId), ]); } }