contextService->getBusinessId($request); } public function bomTree(Request $request, $id) { $bom = Bom::forBusiness($this->businessId($request))->findOrFail($id); return response()->json([ 'bom' => $bom, 'tree' => $this->bomService->buildTree($bom), 'flat' => $this->bomService->explode($bom), ]); } public function buildCostScenario(Request $request) { $data = $request->validate([ 'bom_id' => 'required|integer', 'scenario_code' => 'required|string', 'name' => 'required|string', 'alternate_selections' => 'nullable|array', ]); $bom = Bom::forBusiness($this->businessId($request))->findOrFail($data['bom_id']); $scenario = $this->costingService->buildScenario( $this->businessId($request), $bom, $data['scenario_code'], $data['name'], $data['alternate_selections'] ?? [] ); return response()->json($scenario->load('lines')); } public function compareScenarios(Request $request) { $ids = $request->input('scenario_ids', []); return response()->json($this->costingService->compareScenarios($ids)); } public function lookup(Request $request) { $query = $request->validate(['q' => 'required|string'])['q']; return response()->json($this->traceabilityService->lookup($this->businessId($request), $query)); } public function findStock(Request $request) { $itemId = (int) $request->input('item_master_id'); return response()->json([ 'stock' => $this->sourcingService->findStock($this->businessId($request), $itemId), 'suppliers' => $this->sourcingService->findSuppliers($itemId), ]); } public function installedAsset(Request $request, $id) { $asset = CustomerInstalledAsset::forBusiness($this->businessId($request)) ->with(['customer', 'serializedUnit.components', 'warranties', 'lineRevision']) ->findOrFail($id); return response()->json($asset); } }