where(function ($q) { $q->where('type', 'kit') ->orWhere('type', 'assembly'); }); if ($search = $request->search) { $query->where(function ($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('sku', 'like', "%{$search}%") ->orWhere('category', 'like', "%{$search}%"); }); } $kits = $query->latest() ->paginate(15) ->withQueryString(); return Inertia::render('MaterialsCatalog::MaterialsCatalog/Index', [ 'kits' => $kits, 'filters' => $request->only(['search']) ]); } private function ensureCanManageCatalog(): void { $user = auth()->user(); if ($user && $user->hasAnyRole(['Site Technical', 'Construction Supervisor', 'Site Operations', 'Site Engineer', 'Site Supervisor', 'Field Engineer', 'Safety Officer', 'Quality Inspector', 'Warehouse Staff'])) { abort(403, 'Unauthorized action. Site Operations roles are restricted from modifying catalog kits.'); } } /** * Show the form for creating a new resource. */ public function create() { $this->ensureCanManageCatalog(); $rawMaterials = Material::where('type', 'single')->get(['id', 'name', 'sku', 'unit', 'unit_cost']); return Inertia::render('MaterialsCatalog::MaterialsCatalog/Form', [ 'kit' => null, 'rawMaterials' => $rawMaterials ]); } /** * Store a newly created resource in storage. */ public function store(Request $request) { $this->ensureCanManageCatalog(); $validated = $request->validate([ 'name' => 'required|string|max:255', 'sku' => 'nullable|string|unique:materials,sku', 'category' => 'nullable|string', 'description' => 'nullable|string', 'components' => 'required|array|min:1', 'components.*.component_id' => 'required|exists:materials,id', 'components.*.quantity' => 'required|numeric|min:0.001', ]); $calculatedUnitCost = 0; foreach ($validated['components'] as $comp) { $mat = Material::find($comp['component_id']); if ($mat) { $calculatedUnitCost += ($mat->unit_cost * (float)$comp['quantity']); } } $kit = Material::create([ 'name' => $validated['name'], 'sku' => $validated['sku'], 'category' => $validated['category'] ?? 'Kit', 'description' => $validated['description'], 'unit' => 'kit', 'type' => 'kit', 'unit_cost' => $calculatedUnitCost, ]); $components = []; foreach ($validated['components'] as $comp) { $components[] = new \Modules\MasterData\Models\MaterialComponent([ 'component_id' => $comp['component_id'], 'quantity' => $comp['quantity'], ]); } $kit->components()->saveMany($components); return redirect()->route('materials-catalog.kits.index') ->with('success', 'Kit created successfully.'); } /** * Show the specified resource. */ public function show(string $id) { return redirect()->back(); // Or render a separate show page if needed } /** * Show the form for editing the specified resource. */ public function edit(string $id) { $this->ensureCanManageCatalog(); $kit = Material::with('components')->findOrFail($id); $rawMaterials = Material::where('type', 'single')->get(['id', 'name', 'sku', 'unit', 'unit_cost']); return Inertia::render('MaterialsCatalog::MaterialsCatalog/Form', [ 'kit' => $kit, 'rawMaterials' => $rawMaterials ]); } /** * Update the specified resource in storage. */ public function update(Request $request, string $id) { $this->ensureCanManageCatalog(); $kit = Material::findOrFail($id); $validated = $request->validate([ 'name' => 'required|string|max:255', 'sku' => 'nullable|string|unique:materials,sku,' . $kit->id, 'category' => 'nullable|string', 'description' => 'nullable|string', 'components' => 'required|array|min:1', 'components.*.component_id' => 'required|exists:materials,id', 'components.*.quantity' => 'required|numeric|min:0.001', ]); $calculatedUnitCost = 0; foreach ($validated['components'] as $comp) { $mat = Material::find($comp['component_id']); if ($mat) { $calculatedUnitCost += ($mat->unit_cost * (float)$comp['quantity']); } } $kit->update([ 'name' => $validated['name'], 'sku' => $validated['sku'], 'category' => $validated['category'] ?? 'Kit', 'description' => $validated['description'], 'unit_cost' => $calculatedUnitCost, ]); $kit->components()->delete(); // Clear old components $components = []; foreach ($validated['components'] as $comp) { $components[] = new \Modules\MasterData\Models\MaterialComponent([ 'component_id' => $comp['component_id'], 'quantity' => $comp['quantity'], ]); } $kit->components()->saveMany($components); return redirect()->route('materials-catalog.kits.index') ->with('success', 'Kit updated successfully.'); } /** * Remove the specified resource from storage. */ public function destroy(string $id) { $this->ensureCanManageCatalog(); $kit = Material::findOrFail($id); $kit->delete(); return back()->with('success', 'Kit deleted successfully.'); } }