207 lines
7.1 KiB
PHP
207 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Slot;
|
|
use App\Models\VendingMachine;
|
|
use App\Models\Product;
|
|
use App\Models\SlotProduct;
|
|
use App\Http\Controllers\Concerns\HasTenantSecurity;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
use Illuminate\Http\RedirectResponse;
|
|
|
|
class SlotController extends Controller
|
|
{
|
|
use HasTenantSecurity;
|
|
public function index(Request $request): View
|
|
{
|
|
$this->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.');
|
|
}
|
|
}
|