authorizeIe('ie.costing.view'); $businessId = $this->businessId(); if ($request->ajax()) { return DataTables::of(CostScenario::forBusiness($businessId)->with('bom')) ->addColumn('bom_code', fn ($row) => $row->bom?->bom_code ?? '—') ->addColumn('total_cost_fmt', fn ($row) => number_format((float) $row->total_cost, 2)) ->addColumn('action', fn ($row) => '') ->rawColumns(['action']) ->make(true); } return view('industrialengineering::cost_scenarios.index'); } public function create() { $this->authorizeIe('ie.costing.create'); $revisions = LineRevision::forBusiness($this->businessId()) ->with(['boms' => fn ($q) => $q->where('bom_type', 'mbom')]) ->get(); return view('industrialengineering::cost_scenarios.create', compact('revisions')); } public function store(Request $request) { $this->authorizeIe('ie.costing.create'); $data = $request->validate([ 'bom_id' => 'required|exists:ie_boms,id', 'scenario_code' => 'required|string|max:100', 'name' => 'required|string|max:255', ]); $bom = \Modules\IndustrialEngineering\Models\Bom::forBusiness($this->businessId())->findOrFail($data['bom_id']); $scenario = $this->costingService->buildScenario( $this->businessId(), $bom, $data['scenario_code'], $data['name'] ); return redirect()->action([self::class, 'show'], $scenario->id) ->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.scenario_created')]); } public function show($id) { $this->authorizeIe('ie.costing.view'); $scenario = CostScenario::forBusiness($this->businessId()) ->with(['lines.itemMaster', 'lines.selectedAlternateItem', 'bom']) ->findOrFail($id); return view('industrialengineering::cost_scenarios.show', compact('scenario')); } public function compare(Request $request) { $this->authorizeIe('ie.costing.view'); $ids = $request->input('scenario_ids', []); $comparison = $this->costingService->compareScenarios($ids); return response()->json($comparison); } }