BFI cart addItem method & test

This commit is contained in:
Fabian @ Blax Software 2025-12-09 09:42:59 +01:00
parent beebee6b82
commit 6fede41426
2 changed files with 47 additions and 11 deletions

View File

@ -137,30 +137,65 @@ class Cart extends Model
});
}
/**
* Add an item to the cart or increase quantity if it already exists.
*
* @param Model&Cartable $cartable The item to add to cart
* @param int $quantity The quantity to add
* @param array<string, mixed> $parameters Additional parameters for the cart item
* @return CartItem
* @throws \Exception If the item doesn't implement Cartable interface
*/
public function addToCart(
Model $cartable,
$quantity = 1,
$parameters = []
int $quantity = 1,
array $parameters = []
): CartItem {
// $cartable must implement Cartable
if (! $cartable instanceof Cartable) {
throw new \Exception("Item must implement the Cartable interface.");
}
// Check if item already exists in cart with same parameters
$existingItem = $this->items()
->where('purchasable_id', $cartable->getKey())
->where('purchasable_type', get_class($cartable))
->get()
->first(function ($item) use ($parameters) {
$existingParams = is_array($item->parameters)
? $item->parameters
: (array) $item->parameters;
// Sort both arrays to ensure consistent comparison
ksort($existingParams);
ksort($parameters);
return $existingParams === $parameters;
});
if ($existingItem) {
// Update quantity and subtotal
$newQuantity = $existingItem->quantity + $quantity;
$existingItem->update([
'quantity' => $newQuantity,
'subtotal' => ($cartable->getCurrentPrice()) * $newQuantity,
]);
return $existingItem->fresh();
}
// Create new cart item
$cartItem = $this->items()->create([
'purchasable_id' => $cartable->getKey(),
'purchasable_type' => get_class($cartable),
'quantity' => $quantity,
'price' => $cartable?->getCurrentPrice(),
'regular_price' => $cartable?->getCurrentPrice(false) ?? $cartable?->unit_amount,
'subtotal' => ($cartable?->getCurrentPrice()) * $quantity,
'price' => $cartable->getCurrentPrice(),
'regular_price' => $cartable->getCurrentPrice(false) ?? $cartable->unit_amount,
'subtotal' => ($cartable->getCurrentPrice()) * $quantity,
'parameters' => $parameters,
]);
$cartItem = $cartItem->fresh();
return $cartItem;
return $cartItem->fresh();
}
public function checkout(): static

View File

@ -319,6 +319,7 @@ class CartManagementTest extends TestCase
);
$this->assertCount(2, $cart->fresh()->items);
$this->assertEquals($productPrice->unit_amount * 3, $cart->getTotal());
}
/** @test */