140 lines
4.7 KiB
PHP
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'));
|
|
}
|
|
}
|