ensureCorrectTenantSession(); $tenantId = $this->getCurrentTenantId(); $query = Slot::with(['vendingMachine', 'products']); // Filter nach Mandant über vending_machines if ($tenantId) { $query->whereHas('vendingMachine', function ($q) use ($tenantId) { $q->where('tenant_id', $tenantId); }); } // Filter nach Automat if ($request->filled('machine')) { $query->where('vending_machine_id', $request->machine); } // Filter nach Status if ($request->filled('status')) { if ($request->status === 'occupied') { $query->whereHas('products'); } elseif ($request->status === 'empty') { $query->whereDoesntHave('products'); } } $slots = $query->paginate(15); return view('admin.slots.index', compact('slots')); } public function create(): View { $this->ensureCorrectTenantSession(); $tenantId = $this->getCurrentTenantId(); $query = VendingMachine::where('is_active', true); if ($tenantId) { $query->where('tenant_id', $tenantId); } $vendingMachines = $query->get(); return view('admin.slots.create', compact('vendingMachines')); } public function store(Request $request): RedirectResponse { $this->ensureCorrectTenantSession(); $validated = $request->validate([ 'vending_machine_id' => 'required|exists:vending_machines,id', 'slot_number' => 'required|string|max:20', 'position' => 'nullable|string|max:100', 'capacity' => 'required|integer|min:1|max:50', 'is_active' => 'boolean' ]); // Prüfe ob der Automat zum aktuellen Mandanten gehört $vendingMachine = VendingMachine::findOrFail($validated['vending_machine_id']); $this->ensureTenantAccess($vendingMachine->tenant_id); $validated['is_active'] = $request->has('is_active'); Slot::create($validated); return redirect()->route('slots.index')->with('success', 'Fach erfolgreich erstellt.'); } public function show(Slot $slot): View { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $slot->load(['vendingMachine', 'products']); // Filtere Produkte nach Mandant $tenantId = $this->getCurrentTenantId(); $query = Product::query(); if ($tenantId) { $query->where('tenant_id', $tenantId); } $products = $query->get(); return view('admin.slots.show', compact('slot', 'products')); } public function edit(Slot $slot): View { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $tenantId = $this->getCurrentTenantId(); $query = VendingMachine::where('is_active', true); if ($tenantId) { $query->where('tenant_id', $tenantId); } $vendingMachines = $query->get(); return view('admin.slots.edit', compact('slot', 'vendingMachines')); } public function update(Request $request, Slot $slot): RedirectResponse { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $validated = $request->validate([ 'vending_machine_id' => 'required|exists:vending_machines,id', 'slot_number' => 'required|string|max:20', 'position' => 'nullable|string|max:100', 'capacity' => 'required|integer|min:1|max:50', 'is_active' => 'boolean' ]); // Prüfe ob der neue Automat zum aktuellen Mandanten gehört $vendingMachine = VendingMachine::findOrFail($validated['vending_machine_id']); $this->ensureTenantAccess($vendingMachine->tenant_id); $validated['is_active'] = $request->has('is_active'); $slot->update($validated); return redirect()->route('slots.index')->with('success', 'Fach erfolgreich aktualisiert.'); } public function destroy(Slot $slot): RedirectResponse { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $slot->delete(); return redirect()->route('slots.index')->with('success', 'Fach erfolgreich gelöscht.'); } public function attachProduct(Request $request, Slot $slot, Product $product): RedirectResponse { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $validated = $request->validate([ 'product_id' => 'required|exists:products,id', 'stock_quantity' => 'required|integer|min:0|max:' . $slot->capacity, 'price' => 'nullable|numeric|min:0' ]); $actualProduct = Product::findOrFail($validated['product_id']); // Prüfe ob das Produkt zum aktuellen Mandanten gehört $this->ensureTenantAccess($actualProduct->tenant_id); $currentPrice = $validated['price'] ?? $actualProduct->price; // Entferne zuerst alle bestehenden Produkte aus diesem Slot $slot->products()->detach(); // Füge das neue Produkt hinzu $slot->products()->attach($actualProduct->id, [ 'quantity' => $validated['stock_quantity'], 'current_price' => $currentPrice ]); return redirect()->route('slots.show', $slot)->with('success', 'Produkt erfolgreich dem Slot zugeordnet.'); } public function detachProduct(Slot $slot, Product $product): RedirectResponse { $this->ensureCorrectTenantSession(); $this->ensureTenantAccess($slot->vendingMachine->tenant_id); $this->ensureTenantAccess($product->tenant_id); $slot->products()->detach($product->id); return redirect()->route('slots.show', $slot)->with('success', 'Produkt aus dem Slot entfernt.'); } public function updateProduct(Request $request, Slot $slot, Product $product): RedirectResponse { $validated = $request->validate([ 'quantity' => 'required|integer|min:0|max:' . $slot->capacity, 'current_price' => 'nullable|numeric|min:0' ]); $slot->products()->updateExistingPivot($product->id, [ 'quantity' => $validated['quantity'], 'current_price' => $validated['current_price'] ?? $product->price ]); return redirect()->route('slots.show', $slot)->with('success', 'Produktdaten aktualisiert.'); } }