authorizeIe('ie.traceability.view'); $businessId = $this->businessId(); if ($request->ajax()) { return DataTables::of(SerializedUnit::forBusiness($businessId)->with('lineRevision')) ->addColumn('revision_label', fn ($row) => $row->lineRevision?->revision_code ?? '—') ->addColumn('action', fn ($row) => '') ->rawColumns(['action']) ->make(true); } return view('industrialengineering::serialized_units.index'); } public function create() { $this->authorizeIe('ie.traceability.create'); return view('industrialengineering::serialized_units.create'); } public function store(Request $request) { $this->authorizeIe('ie.traceability.create'); $data = $request->validate([ 'unit_code' => 'required|string|max:100', 'serial_number' => 'required|string|max:100', 'line_revision_id' => 'nullable|exists:ie_line_revisions,id', 'release_package_id' => 'nullable|exists:ie_release_packages,id', 'work_order_id' => 'nullable|exists:ie_manufacturing_work_orders,id', ]); $unit = $this->traceabilityService->createSerializedUnit( $this->businessId(), $data['unit_code'], $data['serial_number'], $data['release_package_id'] ?? null, $data['work_order_id'] ?? null, $data['line_revision_id'] ?? null ); return redirect()->action([self::class, 'show'], $unit->id) ->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.unit_created')]); } public function show($id) { $this->authorizeIe('ie.traceability.view'); $unit = SerializedUnit::forBusiness($this->businessId()) ->with(['components.itemMaster', 'components.children', 'genealogyEvents', 'installedAsset.customer', 'lineRevision']) ->findOrFail($id); return view('industrialengineering::serialized_units.show', compact('unit')); } public function addComponent(Request $request, $id) { $this->authorizeIe('ie.traceability.create'); $unit = SerializedUnit::forBusiness($this->businessId())->findOrFail($id); $data = $request->validate([ 'component_label' => 'required|string|max:255', 'position_code' => 'nullable|string|max:100', 'serial_number' => 'nullable|string|max:100', 'item_master_id' => 'nullable|exists:ie_item_masters,id', 'manufacturer' => 'nullable|string|max:100', 'brand' => 'nullable|string|max:100', 'model' => 'nullable|string|max:100', 'warranty_provider' => 'nullable|string|max:100', 'warranty_expires_at' => 'nullable|date', 'parent_component_id' => 'nullable|exists:ie_serialized_unit_components,id', ]); $this->traceabilityService->recordComponentInstallation($unit, $data, auth()->id()); return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.component_recorded')]); } public function completeBuild($id) { $this->authorizeIe('ie.traceability.create'); $unit = SerializedUnit::forBusiness($this->businessId())->findOrFail($id); $this->traceabilityService->completeBuild($unit); return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.build_completed')]); } }