From 06b45cc9b3dd01177f372095394086a53c1fd7ff Mon Sep 17 00:00:00 2001 From: "Fabian @ Blax Software" Date: Fri, 19 Dec 2025 10:08:24 +0100 Subject: [PATCH] I cart set dates, A test --- src/Models/Cart.php | 26 ++++-- tests/Feature/CartDateManagementTest.php | 111 ++++++++++++++++++++++- 2 files changed, 128 insertions(+), 9 deletions(-) diff --git a/src/Models/Cart.php b/src/Models/Cart.php index 88f6049..8eb51d4 100644 --- a/src/Models/Cart.php +++ b/src/Models/Cart.php @@ -312,32 +312,44 @@ class Cart extends Model * 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 $overwrite If true, overwrites existing item dates. If false, only sets null fields. * @return $this * @throws NotEnoughAvailableInTimespanException */ - public function applyDatesToItems(bool $validateAvailability = true): self + public function applyDatesToItems(bool $validateAvailability = true, bool $overwrite = false): self { if (!$this->from || !$this->until) { return $this; } foreach ($this->items as $item) { - // Only apply to booking items that don't already have dates set - if ($item->is_booking && (!$item->from || !$item->until)) { + // Only apply to booking items + 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) { $product = $item->purchasable; - if ($product && !$product->isAvailableForBooking($this->from, $this->until, $item->quantity)) { + if ($product && !$product->isAvailableForBooking($fromDate, $untilDate, $item->quantity)) { throw new NotEnoughAvailableInTimespanException( productName: $product->name ?? 'Product', requested: $item->quantity, available: 0, // Could calculate actual available amount - from: $this->from, - until: $this->until + from: $fromDate, + until: $untilDate ); } } - $item->updateDates($this->from, $this->until); + $item->updateDates($fromDate, $untilDate); } } diff --git a/tests/Feature/CartDateManagementTest.php b/tests/Feature/CartDateManagementTest.php index 76c4695..def6fba 100644 --- a/tests/Feature/CartDateManagementTest.php +++ b/tests/Feature/CartDateManagementTest.php @@ -258,14 +258,121 @@ class CartDateManagementTest extends TestCase $cartUntilDate = Carbon::now()->addDays(3); $cart->setDates($cartFromDate, $cartUntilDate, validateAvailability: false); - $cart->applyDatesToItems(validateAvailability: false); + $cart->applyDatesToItems(validateAvailability: false, overwrite: false); $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($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 */ public function is_ready_to_checkout_uses_cart_fallback_dates() {