authorizeIe('ie.bom.view'); $businessId = $this->businessId(); if ($request->ajax()) { $query = Bom::forBusiness($businessId)->with('lineRevision'); return DataTables::of($query) ->addColumn('revision_label', fn ($row) => $row->lineRevision?->revision_code ?? '—') ->addColumn('action', fn ($row) => '') ->rawColumns(['action']) ->make(true); } return view('industrialengineering::boms.index'); } public function show($id) { $this->authorizeIe('ie.bom.view'); $bom = Bom::forBusiness($this->businessId())->findOrFail($id); $tree = $this->bomService->buildTree($bom); $flat = $this->bomService->explode($bom); return view('industrialengineering::boms.show', compact('bom', 'tree', 'flat')); } public function create(Request $request) { $this->authorizeIe('ie.bom.create'); $revisions = LineRevision::forBusiness($this->businessId())->orderByDesc('id')->pluck('revision_code', 'id'); return view('industrialengineering::boms.create', [ 'revisions' => $revisions, 'bomTypes' => ['ebom' => __('industrialengineering::lang.ebom'), 'mbom' => __('industrialengineering::lang.mbom'), 'sbom' => __('industrialengineering::lang.sbom')], 'suggestedCode' => $this->suggestCode('bom'), ]); } public function store(Request $request) { $this->authorizeIe('ie.bom.create'); $data = $request->validate([ 'line_revision_id' => 'nullable|exists:ie_line_revisions,id', 'bom_type' => 'required|in:ebom,mbom,sbom', 'bom_code' => 'nullable|string|max:100', 'name' => 'required|string|max:255', 'revision_code' => 'nullable|string|max:20', ]); $codes = $this->resolveCodes('bom', $data['bom_code'] ?? null, new Bom(), 'bom_code'); $data = array_merge($data, $codes); $data['business_id'] = $this->businessId(); $data['revision_code'] = $data['revision_code'] ?? 'A'; Bom::create($data); return redirect()->action([self::class, 'index'])->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.saved')]); } public function deriveSbom($id) { $this->authorizeIe('ie.bom.create'); $mbom = Bom::forBusiness($this->businessId())->where('bom_type', 'mbom')->findOrFail($id); $sbom = $this->bomService->deriveServiceBom($mbom, $this->businessId(), $mbom->bom_code.'-SBOM'); return redirect()->action([self::class, 'show'], $sbom->id) ->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.sbom_derived')]); } public function storeLine(Request $request, $id) { $this->authorizeIe('ie.bom.create'); $bom = \Modules\IndustrialEngineering\Models\Bom::forBusiness($this->businessId())->findOrFail($id); $data = $request->validate([ 'item_master_id' => 'required|exists:ie_item_masters,id', 'parent_line_id' => 'nullable|exists:ie_bom_lines,id', 'quantity' => 'required|numeric|min:0.0001', 'position_code' => 'nullable|string|max:100', 'alternate_group' => 'nullable|string|max:50', 'is_serviceable' => 'nullable|boolean', ]); \Modules\IndustrialEngineering\Models\BomLine::create(array_merge($data, [ 'business_id' => $this->businessId(), 'bom_id' => $bom->id, 'is_serviceable' => $request->boolean('is_serviceable', true), 'sort_order' => (int) $bom->lines()->max('sort_order') + 10, ])); return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.saved')]); } }