generated from boboko/starter
90 lines
2.7 KiB
PHP
90 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Checkout;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
use Lunar\Models\ProductVariant;
|
|
use Modules\Core\Cart\Exceptions\InvalidCouponException;
|
|
use Modules\Core\Cart\Services\CartService;
|
|
|
|
/**
|
|
* Thin storefront cart endpoints for the checkout module. Every action mutates
|
|
* the session cart via boboko-core's CartService and returns the same
|
|
* server-rendered `cart-body` partial — the drawer's Stimulus controller swaps
|
|
* that fragment in place (no JSON, no client-side templating). $cart / $lines
|
|
* for the partial come from the view composer in CheckoutModuleServiceProvider.
|
|
*/
|
|
class CartController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly CartService $cart,
|
|
) {}
|
|
|
|
public function add(string $locale, Request $request): View
|
|
{
|
|
$data = $request->validate([
|
|
'purchasable_id' => ['required', 'integer'],
|
|
'quantity' => ['nullable', 'integer', 'min:1'],
|
|
]);
|
|
|
|
$variant = ProductVariant::findOrFail($data['purchasable_id']);
|
|
|
|
$this->cart->addLine($variant, $data['quantity'] ?? 1);
|
|
|
|
return view('checkout::partials.cart-body');
|
|
}
|
|
|
|
public function updateLine(string $locale, Request $request, int $line): View
|
|
{
|
|
$quantity = (int) $request->validate([
|
|
'quantity' => ['required', 'integer', 'min:0'],
|
|
])['quantity'];
|
|
|
|
$quantity === 0
|
|
? $this->cart->removeLine($line)
|
|
: $this->cart->updateLine($line, $quantity);
|
|
|
|
return view('checkout::partials.cart-body');
|
|
}
|
|
|
|
public function remove(string $locale, int $line): View
|
|
{
|
|
$this->cart->removeLine($line);
|
|
|
|
return view('checkout::partials.cart-body');
|
|
}
|
|
|
|
/**
|
|
* A bad code is a normal, expected outcome here (typo, expired code), not
|
|
* an error state for the request — it re-renders the same cart-body
|
|
* partial with $couponError set, rather than a 4xx/redirect, so the fetch
|
|
* + swap in bbk-cart-controller stays the one code path for every cart
|
|
* mutation.
|
|
*/
|
|
public function applyCoupon(string $locale, Request $request): View
|
|
{
|
|
$code = $request->validate([
|
|
'code' => ['required', 'string'],
|
|
])['code'];
|
|
|
|
$couponError = false;
|
|
|
|
try {
|
|
$this->cart->applyCoupon($code);
|
|
} catch (InvalidCouponException) {
|
|
$couponError = true;
|
|
}
|
|
|
|
return view('checkout::partials.cart-body', ['couponError' => $couponError]);
|
|
}
|
|
|
|
public function removeCoupon(string $locale): View
|
|
{
|
|
$this->cart->removeCoupon();
|
|
|
|
return view('checkout::partials.cart-body');
|
|
}
|
|
}
|