authorizeIe('ie.costing.view'); $boms = Bom::forBusiness($this->businessId()) ->where('bom_type', 'mbom') ->with('lineRevision') ->orderByDesc('id') ->get(); $locations = BusinessLocation::forDropdown($this->businessId(), false, true); $suppliers = Contact::suppliersDropdown($this->businessId(), false); return view('industrialengineering::mrp.index', compact('boms', 'locations', 'suppliers')); } public function run(Request $request) { $this->authorizeIe('ie.costing.create'); if ($request->filled('line_id')) { return $this->runForLine($request, (int) $request->input('line_id')); } if ($request->filled('bom_id')) { return $this->runForBom($request, (int) $request->input('bom_id')); } $msg = __('industrialengineering::lang.mrp_missing_context'); return back()->with('status', ['success' => false, 'msg' => $msg]); } protected function runForLine(Request $request, int $lineId) { $line = LineTemplate::forBusiness($this->businessId()) ->productionLines() ->with(['revisions.boms', 'bom']) ->findOrFail($lineId); $ensured = $this->autoIntegration->ensureLineMbom($line); $revision = $ensured['revision']; $mbom = $ensured['mbom']; if (! $mbom) { return back()->with('status', [ 'success' => false, 'msg' => __('industrialengineering::lang.no_mbom_for_line', ['line' => $line->name]), ]); } return $this->executeRun($request, $mbom, $revision); } protected function runForBom(Request $request, int $bomId) { $bom = Bom::forBusiness($this->businessId()) ->with('lineRevision') ->findOrFail($bomId); $revision = $bom->lineRevision; if (! $revision) { return back()->with('status', [ 'success' => false, 'msg' => __('industrialengineering::lang.no_line_revision_for_bom'), ]); } return $this->executeRun($request, $bom, $revision); } protected function executeRun(Request $request, Bom $bom, LineRevision $revision) { $data = $request->validate([ 'planned_quantity' => 'nullable|numeric|min:0.0001', 'location_id' => 'nullable|integer', 'supplier_contact_id' => 'nullable|integer', 'create_purchase_orders' => 'nullable|boolean', 'create_work_order' => 'nullable|boolean', ]); try { $run = $this->mrpService->run( $this->businessId(), $bom, $revision, (float) ($data['planned_quantity'] ?? 1), isset($data['location_id']) ? (int) $data['location_id'] : null, $request->boolean('create_purchase_orders', true), $request->boolean('create_work_order', true), isset($data['supplier_contact_id']) ? (int) $data['supplier_contact_id'] : null, $request->boolean('force_mrp', false) ); } catch (\Throwable $e) { report($e); return back()->with('status', [ 'success' => false, 'msg' => OperationErrorMessages::for($e), ]); } return back()->with('status', [ 'success' => true, 'msg' => $this->completionMessage($run), ]); } protected function completionMessage(MrpRun $run): string { return __('industrialengineering::lang.mrp_completed', [ 'po' => count($run->purchase_order_ids ?? []), 'wo' => $run->work_order_id ? $run->workOrder?->work_order_number : '—', ]); } }