ldc-boutique-cnc/app/Http/Controllers/Fo/BasketController.php
2023-04-25 21:52:27 +02:00

168 lines
5.5 KiB
PHP

<?php
namespace App\Http\Controllers\Fo;
use App\Enums\Product\WeightUnit;
use App\Http\Controllers\Controller;
use App\Lib\Helpers\ToolboxHelper;
use App\Models\Merchandise\Product;
use Gloudemans\Shoppingcart\CartItem;
use Illuminate\Validation\ValidationException;
class BasketController extends Controller
{
/**
* Get Basket
*
* @return \Illuminate\Http\JsonResponse
*/
public function getBasket()
{
$this->authorize('useBasketSystem', Product::class);
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
return \response()->json(ToolboxHelper::cartToList($basket));
}
/**
* Ajout d'un produit au panier
*
* ! Assert Model found, status true and orderable true.
*
* @param \App\Models\Merchandise\Product $product
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Validation\ValidationException Si le produit n'est pas disponible (orderable).
*/
public function addToBasket(Product $product)
{
$this->authorize('useBasketSystem', Product::class);
$this->authorize('addToCart', $product);
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
$basket = $this->filterBasketKeepOnlyOrderableItems($basket);
if (!$product->status or !$product->orderable) {
throw ValidationException::withMessages([
'error' => \trans('Ce produit n\'est plus disponible')
]);
}
$cartItemOptions = \array_merge($this->cartItemOptionsSkel, [
'reference' => $product->reference,
'slug' => $product->slug,
'picture' => $product->picture,
'sell_unit' => $product->sell_unit,
'weight_with_unit' => WeightUnit::getDisplayableWeight($product->weight),
// * Prix ttc du produit
'price_ttc' => $product->price_ttc,
// * Prix ttc du produit remisé
'undiscounted_price_ttc' => $product->undiscounted_price_ttc,
'tax_rate' => $product->tax_rate->rate,
'discount_type' => \optional(\optional($product->discount)->type)->value,
'discount_rate' => $product->discount_rate,
]);
$cartItem = CartItem::fromBuyable($product, $cartItemOptions);
$cartItem->setQuantity(1);
$cartItem->associate($product);
// * Validate Cart Item.
$jsonCartObject = \json_decode($cartItem->toJson());
if (!ToolboxHelper::basketObjectIsValid($jsonCartObject)) {
throw ValidationException::withMessages([
'error' => \trans('Cart item is not valid')
]);
}
$basket->addCartItem($cartItem);
// ! https://github.com/bumbummen99/LaravelShoppingcart/pull/181
// * Note Lib is is actually refactoring for laravel 9 php8 only
// * https://github.com/bumbummen99/LaravelShoppingcart/pull/145
// ! These lines are required to prevent amount bug (after adding to basket).
// ! This because of the cart calculator I guess.
$cartItem->setTaxRate($product->tax_rate->rate / 100);
$cartItem->setDiscountRate($product->discount_rate);
return \response()->json(ToolboxHelper::cartToList($basket));
}
/**
* Retrait d'un produit du panier (1 quantité d'1 type)
*
* @param \App\Models\Merchandise\Product $product
* @return \Illuminate\Http\JsonResponse
*/
public function removeFromBasket(Product $product)
{
$this->authorize('useBasketSystem', Product::class);
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
/** @var \Gloudemans\Shoppingcart\CartItem|null */
$basketItem = $basket->content()->where('id', $product->id)->first();
/** @var string|null */
$rowId = \optional($basketItem)->rowId;
/** @var integer|null */
$qty = \optional($basketItem)->qty;
if ($rowId and !\is_null($qty)) {
$basket->update($rowId, $qty - 1);
}
$basket = $this->filterBasketKeepOnlyOrderableItems($basket);
return \response()->json(ToolboxHelper::cartToList($basket));
}
/**
* Retrait d'un type produit du panier (toute les quantités d'1 type)
*
* @param \App\Models\Merchandise\Product $product
* @return \Illuminate\Http\JsonResponse
*/
public function removeItemTypeFromBasket(Product $product)
{
$this->authorize('useBasketSystem', Product::class);
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
/** @var \Gloudemans\Shoppingcart\CartItem|null */
$basketItem = $basket->content()->where('id', $product->id)->first();
/** @var string|null */
$rowId = \optional($basketItem)->rowId;
if ($rowId) {
$basket->remove($rowId);
}
$basket = $this->filterBasketKeepOnlyOrderableItems($basket);
return \response()->json(ToolboxHelper::cartToList($basket));
}
/**
* Retrait d'un type produit du panier (toute les quantités d'1 type)
*
* @return \Illuminate\Http\JsonResponse
*/
public function emptyBasket()
{
$this->authorize('useBasketSystem', Product::class);
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
$basket->destroy();
/** @var \Gloudemans\Shoppingcart\Cart */
$basket = app('basket');
return \response()->json(ToolboxHelper::cartToList($basket));
}
}