Projects/3BIT/winter-semester/IIS/xnecasr00/app/Http/Controllers/PurchaseController.php
2026-04-14 19:28:46 +02:00

140 lines
4.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Purchase;
use App\Models\Wine;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;
class PurchaseController extends BaseController
{
/**
* List purchases (simple index)
*/
public function index()
{
$purchases = Purchase::with(['user','items.wine'])->latest()->paginate(20);
return response()->json($purchases);
}
/**
* Store a new purchase with items.
*
* Expected payload:
* {
* user_id: int,
* status: string,
* items: [ { wine_id: int, quantity: int, unit_price?: decimal }, ... ]
* }
*/
public function store(Request $request)
{
$data = $request->validate([
'user_id' => 'required|integer|exists:users,id',
'status' => 'nullable|string',
'items' => 'required|array|min:1',
'items.*.wine_id' => 'required|integer|exists:wines,wine_id',
'items.*.quantity' => 'required|integer|min:1',
'items.*.unit_price' => 'nullable|numeric|min:0',
]);
try {
$purchase = Purchase::createWithItems([
'user_id' => $data['user_id'],
'status' => $data['status'] ?? 'pending',
], $data['items']);
return response()->json(['success' => true, 'purchase' => $purchase->load(['items.wine','user'])], 201);
} catch (\Exception $e) {
return response()->json(['success' => false, 'message' => $e->getMessage()], 422);
}
}
/**
* Process checkout from shopping cart
*/
public function checkout(Request $request)
{
$validated = $request->validate([
'full_name' => 'required|string|max:255',
'phone' => ['required', 'string', 'max:20', 'regex:/^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/'],
'country' => 'required|string|max:100',
'street' => 'required|string|max:255',
'city' => 'required|string|max:255',
'postal_code' => ['required', 'string', 'max:20', 'regex:/^[0-9]{3}\s?[0-9]{2}$/'],
], [
'phone.regex' => 'The phone number format is invalid. Please use format: +420 123 456 789',
'postal_code.regex' => 'The postal code format is invalid. Please use format: 123 45',
]);
$cart = Session::get('cart', []);
if (empty($cart)) {
return redirect()->route('cart.index')->with('error', 'Košík je prázdny.');
}
// Prepare items for purchase creation
$items = [];
foreach ($cart as $wineId => $cartItem) {
$wine = Wine::find($wineId);
if (!$wine) {
continue;
}
// Check stock
if ($wine->bottles_in_stock < $cartItem['quantity']) {
return redirect()->route('cart.index')
->with('error', "Nedostatočné množstvo na sklade pre {$wine->wine_name}.");
}
$items[] = [
'wine_id' => $wineId,
'quantity' => $cartItem['quantity'],
'unit_price' => $wine->price_per_bottle,
];
}
try {
// Create purchase with invoice details in note
$invoiceNote = "Name: {$validated['full_name']}\n" .
"Phone: {$validated['phone']}\n" .
"Street: {$validated['street']}\n" .
"City: {$validated['city']}\n" .
"Postal Code: {$validated['postal_code']}\n" .
"Country: {$validated['country']}";
$purchase = Purchase::createWithItems([
'user_id' => Auth::id(),
'status' => 'completed',
'note' => $invoiceNote,
'purchased_at' => now(),
], $items);
// Clear cart after successful purchase
Session::forget('cart');
return redirect()->route('purchases.my')
->with('success', 'Objednávka bola úspešne vytvorená!');
} catch (\Exception $e) {
return redirect()->route('cart.index')
->with('error', 'Chyba pri vytváraní objednávky: ' . $e->getMessage());
}
}
/**
* Display customer's purchase history
*/
public function myPurchases()
{
$purchases = Purchase::with(['items.wine.grapeVariety'])
->where('user_id', Auth::id())
->orderBy('purchased_at', 'desc')
->orderBy('created_at', 'desc')
->get();
return view('purchases.my', compact('purchases'));
}
}