authorizeIe('ie.release.view'); $businessId = $this->businessId(); if ($request->ajax()) { return DataTables::of(ReleasePackage::forBusiness($businessId)->with('lineRevision')) ->addColumn('revision_label', fn ($row) => $row->lineRevision?->revision_code ?? '—') ->addColumn('action', fn ($row) => '') ->rawColumns(['action']) ->make(true); } return view('industrialengineering::release_packages.index'); } public function create() { $this->authorizeIe('ie.release.create'); $revisions = LineRevision::forBusiness($this->businessId()) ->whereIn('status', ['approved', 'released', 'draft']) ->with(['boms' => fn ($q) => $q->where('bom_type', 'mbom')]) ->get(); return view('industrialengineering::release_packages.create', compact('revisions')); } public function store(Request $request) { $this->authorizeIe('ie.release.create'); $data = $request->validate([ 'line_revision_id' => 'required|exists:ie_line_revisions,id', 'mbom_id' => 'required|exists:ie_boms,id', 'cost_scenario_id' => 'nullable|exists:ie_cost_scenarios,id', 'package_code' => 'required|string|max:100', 'name' => 'required|string|max:255', ]); $revision = LineRevision::forBusiness($this->businessId())->findOrFail($data['line_revision_id']); $mbom = Bom::forBusiness($this->businessId())->findOrFail($data['mbom_id']); $cost = ! empty($data['cost_scenario_id']) ? CostScenario::forBusiness($this->businessId())->find($data['cost_scenario_id']) : null; $package = $this->releaseService->createReleasePackage( $this->businessId(), $revision, $mbom, $cost, $data['package_code'], $data['name'] ); $this->releaseService->requestSignoffs($package); return redirect()->action([self::class, 'show'], $package->id) ->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.release_created')]); } public function show($id) { $this->authorizeIe('ie.release.view'); $package = ReleasePackage::forBusiness($this->businessId()) ->with(['signoffs', 'workOrders', 'lineRevision', 'mbom', 'costScenario']) ->findOrFail($id); return view('industrialengineering::release_packages.show', compact('package')); } public function signoff(Request $request, $id) { $this->authorizeIe('ie.release.approve'); $data = $request->validate(['role' => 'required|string', 'status' => 'required|in:approved,rejected']); $package = ReleasePackage::forBusiness($this->businessId())->findOrFail($id); $this->releaseService->signoff($package, $data['role'], auth()->id(), $data['status']); return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.signoff_recorded')]); } public function release($id) { $this->authorizeIe('ie.release.approve'); $package = ReleasePackage::forBusiness($this->businessId())->findOrFail($id); try { $this->releaseService->release($package, auth()->id()); } catch (\RuntimeException $e) { return back()->with('status', ['success' => false, 'msg' => $e->getMessage()]); } return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.released_to_production')]); } public function createWorkOrder(Request $request, $id) { $this->authorizeIe('ie.release.create'); $data = $request->validate([ 'work_order_number' => 'required|string|max:100', 'planned_quantity' => 'nullable|numeric|min:0.0001', 'location_id' => 'nullable|integer', ]); $package = ReleasePackage::forBusiness($this->businessId())->findOrFail($id); $wo = $this->releaseService->createWorkOrder( $package, $data['work_order_number'], (float) ($data['planned_quantity'] ?? 1), $data['location_id'] ?? null ); return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.work_order_created', ['number' => $wo->work_order_number])]); } }