I cart set dates, A test

This commit is contained in:
Fabian @ Blax Software 2025-12-19 10:08:24 +01:00
parent f6c60f3d79
commit 06b45cc9b3
2 changed files with 128 additions and 9 deletions

View File

@ -312,32 +312,44 @@ class Cart extends Model
* Apply cart dates to all items that don't have their own dates set. * Apply cart dates to all items that don't have their own dates set.
* *
* @param bool $validateAvailability Whether to validate product availability for the timespan * @param bool $validateAvailability Whether to validate product availability for the timespan
* @param bool $overwrite If true, overwrites existing item dates. If false, only sets null fields.
* @return $this * @return $this
* @throws NotEnoughAvailableInTimespanException * @throws NotEnoughAvailableInTimespanException
*/ */
public function applyDatesToItems(bool $validateAvailability = true): self public function applyDatesToItems(bool $validateAvailability = true, bool $overwrite = false): self
{ {
if (!$this->from || !$this->until) { if (!$this->from || !$this->until) {
return $this; return $this;
} }
foreach ($this->items as $item) { foreach ($this->items as $item) {
// Only apply to booking items that don't already have dates set // Only apply to booking items
if ($item->is_booking && (!$item->from || !$item->until)) { if ($item->is_booking) {
// Determine which dates to apply based on overwrite setting
$shouldApplyFrom = $overwrite || !$item->from;
$shouldApplyUntil = $overwrite || !$item->until;
if (!$shouldApplyFrom && !$shouldApplyUntil) {
continue;
}
$fromDate = $shouldApplyFrom ? $this->from : $item->from;
$untilDate = $shouldApplyUntil ? $this->until : $item->until;
if ($validateAvailability) { if ($validateAvailability) {
$product = $item->purchasable; $product = $item->purchasable;
if ($product && !$product->isAvailableForBooking($this->from, $this->until, $item->quantity)) { if ($product && !$product->isAvailableForBooking($fromDate, $untilDate, $item->quantity)) {
throw new NotEnoughAvailableInTimespanException( throw new NotEnoughAvailableInTimespanException(
productName: $product->name ?? 'Product', productName: $product->name ?? 'Product',
requested: $item->quantity, requested: $item->quantity,
available: 0, // Could calculate actual available amount available: 0, // Could calculate actual available amount
from: $this->from, from: $fromDate,
until: $this->until until: $untilDate
); );
} }
} }
$item->updateDates($this->from, $this->until); $item->updateDates($fromDate, $untilDate);
} }
} }

View File

@ -258,14 +258,121 @@ class CartDateManagementTest extends TestCase
$cartUntilDate = Carbon::now()->addDays(3); $cartUntilDate = Carbon::now()->addDays(3);
$cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false); $cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false);
$cart->applyDatesToItems(validateAvailability: false); $cart->applyDatesToItems(validateAvailability: false, overwrite: false);
$item->refresh(); $item->refresh();
// Item dates should remain unchanged // Item dates should remain unchanged when overwrite is false
$this->assertEquals($itemFromDate->toDateString(), $item->from->toDateString()); $this->assertEquals($itemFromDate->toDateString(), $item->from->toDateString());
$this->assertEquals($itemUntilDate->toDateString(), $item->until->toDateString()); $this->assertEquals($itemUntilDate->toDateString(), $item->until->toDateString());
} }
/** @test */
public function apply_dates_to_items_overwrites_when_overwrite_is_true()
{
$product = Product::factory()->create([
'type' => ProductType::BOOKING,
'manage_stock' => false,
]);
$price = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
'purchasable_type' => Product::class,
'type' => PriceType::RECURRING,
'is_default' => true,
]);
$cart = Cart::factory()->create();
$item = $cart->addToCart($product, 1);
$itemFromDate = Carbon::now()->addDays(5);
$itemUntilDate = Carbon::now()->addDays(7);
$item->updateDates($itemFromDate, $itemUntilDate);
$cartFromDate = Carbon::now()->addDays(1);
$cartUntilDate = Carbon::now()->addDays(3);
$cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false);
$cart->applyDatesToItems(validateAvailability: false, overwrite: true);
$item->refresh();
// Item dates should be overwritten with cart dates when overwrite is true
$this->assertEquals($cartFromDate->toDateString(), $item->from->toDateString());
$this->assertEquals($cartUntilDate->toDateString(), $item->until->toDateString());
}
/** @test */
public function apply_dates_to_items_fills_only_null_from_date_when_overwrite_false()
{
$product = Product::factory()->create([
'type' => ProductType::BOOKING,
'manage_stock' => false,
]);
$price = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
'purchasable_type' => Product::class,
'type' => PriceType::RECURRING,
'is_default' => true,
]);
$cart = Cart::factory()->create();
$item = $cart->addToCart($product, 1);
// Only set 'until' date on the item, leave 'from' as null
$itemUntilDate = Carbon::now()->addDays(7);
$item->until = $itemUntilDate;
$item->save();
$cartFromDate = Carbon::now()->addDays(1);
$cartUntilDate = Carbon::now()->addDays(3);
$cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false);
$cart->applyDatesToItems(validateAvailability: false, overwrite: false);
$item->refresh();
// 'from' should be filled from cart, 'until' should remain unchanged
$this->assertEquals($cartFromDate->toDateString(), $item->from->toDateString());
$this->assertEquals($itemUntilDate->toDateString(), $item->until->toDateString());
}
/** @test */
public function apply_dates_to_items_fills_only_null_until_date_when_overwrite_false()
{
$product = Product::factory()->create([
'type' => ProductType::BOOKING,
'manage_stock' => false,
]);
$price = ProductPrice::factory()->create([
'purchasable_id' => $product->id,
'purchasable_type' => Product::class,
'type' => PriceType::RECURRING,
'is_default' => true,
]);
$cart = Cart::factory()->create();
$item = $cart->addToCart($product, 1);
// Only set 'from' date on the item, leave 'until' as null
$itemFromDate = Carbon::now()->addDays(1);
$item->from = $itemFromDate;
$item->save();
$cartFromDate = Carbon::now()->addDays(5);
$cartUntilDate = Carbon::now()->addDays(7);
$cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false);
$cart->applyDatesToItems(validateAvailability: false, overwrite: false);
$item->refresh();
// 'from' should remain unchanged, 'until' should be filled from cart
$this->assertEquals($itemFromDate->toDateString(), $item->from->toDateString());
$this->assertEquals($cartUntilDate->toDateString(), $item->until->toDateString());
}
/** @test */ /** @test */
public function is_ready_to_checkout_uses_cart_fallback_dates() public function is_ready_to_checkout_uses_cart_fallback_dates()
{ {