From 2303b9f703da50ff8c5bba183be8cc0784627f06 Mon Sep 17 00:00:00 2001 From: "Fabian @ Blax Software" Date: Thu, 18 Dec 2025 10:54:42 +0100 Subject: [PATCH] BF decimals, I test consitency --- src/Models/Cart.php | 11 +- src/Models/CartItem.php | 12 +- src/Services/CartService.php | 2 +- src/Traits/HasBookingPriceCalculation.php | 3 +- tests/Feature/BookingPerMinutePricingTest.php | 102 ++++++------ tests/Feature/CartCheckoutSessionTest.php | 9 +- tests/Feature/PoolPerMinutePricingTest.php | 157 +++++++++--------- 7 files changed, 149 insertions(+), 147 deletions(-) diff --git a/src/Models/Cart.php b/src/Models/Cart.php index b62f9fa..47cc176 100644 --- a/src/Models/Cart.php +++ b/src/Models/Cart.php @@ -648,9 +648,9 @@ class Cart extends Model $days = $this->calculateBookingDays($from, $until); } - // Calculate price per unit for the entire period - $pricePerUnit = $pricePerDay * $days; - $regularPricePerUnit = $regularPricePerDay * $days; + // Calculate price per unit for the entire period and round to nearest cent for consistency + $pricePerUnit = (int) round($pricePerDay * $days); + $regularPricePerUnit = (int) round($regularPricePerDay * $days); // Defensive check - ensure pricePerUnit is not null if ($pricePerUnit === null) { @@ -931,9 +931,8 @@ class Cart extends Model $productName .= " from {$fromFormatted} to {$untilFormatted}"; } - // Convert price to cents (Stripe expects smallest currency unit) - // Cart item price is already per unit for the entire period - $unitAmountCents = (int) round($item->price * 100); + // Price is already stored in cents, Stripe expects smallest currency unit + $unitAmountCents = (int) $item->price; // Build line item using price_data for dynamic pricing $lineItem = [ diff --git a/src/Models/CartItem.php b/src/Models/CartItem.php index bbffb29..17e91eb 100644 --- a/src/Models/CartItem.php +++ b/src/Models/CartItem.php @@ -31,9 +31,9 @@ class CartItem extends Model protected $casts = [ 'quantity' => 'integer', - 'price' => 'decimal:2', - 'regular_price' => 'decimal:2', - 'subtotal' => 'decimal:2', + 'price' => 'integer', + 'regular_price' => 'integer', + 'subtotal' => 'integer', 'parameters' => 'array', 'meta' => 'array', 'from' => 'datetime', @@ -427,9 +427,9 @@ class CartItem extends Model $pricePerDay = $product->getCurrentPrice(null, $this->cart, $from, $until); $regularPricePerDay = $product->getCurrentPrice(false, $this->cart, $from, $until) ?? $pricePerDay; - // Calculate new prices - $pricePerUnit = $pricePerDay * $days; - $regularPricePerUnit = $regularPricePerDay * $days; + // Calculate new prices and round to nearest cent for consistency + $pricePerUnit = (int) round($pricePerDay * $days); + $regularPricePerUnit = (int) round($regularPricePerDay * $days); $this->update([ 'from' => $from, diff --git a/src/Services/CartService.php b/src/Services/CartService.php index 636e9c8..ef42b9b 100644 --- a/src/Services/CartService.php +++ b/src/Services/CartService.php @@ -538,7 +538,7 @@ class CartService // Calculate price based on days for booking products if ($product instanceof Product && ($product->isBooking() || $product->isPool())) { $days = $this->calculateBookingDays($from, $until); - $pricePerUnit = $pricePerDay * $days; // Price for one unit for the entire period + $pricePerUnit = (int) round($pricePerDay * $days); // Price for one unit for the entire period $totalPrice = $pricePerUnit * $quantity; // Total for all units } else { $pricePerUnit = $pricePerDay; diff --git a/src/Traits/HasBookingPriceCalculation.php b/src/Traits/HasBookingPriceCalculation.php index 5c7277a..aaaafe4 100644 --- a/src/Traits/HasBookingPriceCalculation.php +++ b/src/Traits/HasBookingPriceCalculation.php @@ -57,6 +57,7 @@ trait HasBookingPriceCalculation \DateTimeInterface $until ): float { $days = $this->calculateBookingDays($from, $until); - return $pricePerDay * $days; + // Round to nearest cent for consistency and to avoid floating-point precision errors + return (int) round($pricePerDay * $days); } } diff --git a/tests/Feature/BookingPerMinutePricingTest.php b/tests/Feature/BookingPerMinutePricingTest.php index 9cb370d..e22c87b 100644 --- a/tests/Feature/BookingPerMinutePricingTest.php +++ b/tests/Feature/BookingPerMinutePricingTest.php @@ -42,7 +42,7 @@ class BookingPerMinutePricingTest extends TestCase $this->price = ProductPrice::factory()->create([ 'purchasable_id' => $this->bookingProduct->id, 'purchasable_type' => Product::class, - 'unit_amount' => 100, // $100.00 per day + 'unit_amount' => 10000, // $100 per day 'currency' => 'USD', 'is_default' => true, ]); @@ -57,8 +57,8 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // Expecting exactly 100.00 for 1 day - $this->assertEquals('100.00', $cartItem->price); - $this->assertEquals(100.00, $cartItem->subtotal); + $this->assertEquals('10000', $cartItem->price); + $this->assertEquals(10000, $cartItem->subtotal); } /** @test */ @@ -70,8 +70,8 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // Expecting 50.00 for 0.5 days (12 hours) - $this->assertEquals('50.00', $cartItem->price); - $this->assertEquals(50.00, $cartItem->subtotal); + $this->assertEquals('5000', $cartItem->price); + $this->assertEquals(5000, $cartItem->subtotal); } /** @test */ @@ -83,8 +83,8 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // Expecting 150.00 for 1.5 days (36 hours) - $this->assertEquals('150.00', $cartItem->price); - $this->assertEquals(150.00, $cartItem->subtotal); + $this->assertEquals('15000', $cartItem->price); + $this->assertEquals(15000, $cartItem->subtotal); } /** @test */ @@ -96,8 +96,8 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // Expecting 25.00 for 0.25 days (6 hours) - $this->assertEquals('25.00', $cartItem->price); - $this->assertEquals(25.00, $cartItem->subtotal); + $this->assertEquals('2500', $cartItem->price); + $this->assertEquals(2500, $cartItem->subtotal); } /** @test */ @@ -110,8 +110,8 @@ class BookingPerMinutePricingTest extends TestCase // 90 minutes = 1.5 hours = 0.0625 days // Price: 100.00 * 0.0625 = 6.25 - $this->assertEquals('6.25', $cartItem->price); - $this->assertEquals(6.25, $cartItem->subtotal); + $this->assertEquals('625', $cartItem->price); + $this->assertEquals(625, $cartItem->subtotal); } /** @test */ @@ -124,8 +124,8 @@ class BookingPerMinutePricingTest extends TestCase // 51 hours = 2.125 days // Price: 100.00 * 2.125 = 212.50 - $this->assertEquals('212.50', $cartItem->price); - $this->assertEquals(212.50, $cartItem->subtotal); + $this->assertEquals('21250', $cartItem->price); + $this->assertEquals(21250, $cartItem->subtotal); } /** @test */ @@ -138,8 +138,8 @@ class BookingPerMinutePricingTest extends TestCase // 0.5 days * 100.00 = 50.00 per unit // 3 units * 50.00 = 150.00 total - $this->assertEquals('50.00', $cartItem->price); // price per unit - $this->assertEquals(150.00, $cartItem->subtotal); // total for 3 units + $this->assertEquals('5000', $cartItem->price); // price per unit + $this->assertEquals(15000, $cartItem->subtotal); // total for 3 units } /** @test */ @@ -151,15 +151,15 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // Initial price for 1 day - $this->assertEquals('100.00', $cartItem->price); + $this->assertEquals('10000', $cartItem->price); // Update to 18 hours (0.75 days) $newUntil = Carbon::now()->addDays(6)->setTime(3, 0, 0); $cartItem->updateDates($from, $newUntil); // Price should now be 75.00 for 0.75 days - $this->assertEquals(75.00, $cartItem->fresh()->price); - $this->assertEquals(75.00, $cartItem->fresh()->subtotal); + $this->assertEquals(7500, $cartItem->fresh()->price); + $this->assertEquals(7500, $cartItem->fresh()->subtotal); } /** @test */ @@ -172,7 +172,7 @@ class BookingPerMinutePricingTest extends TestCase // 45 minutes = 0.75 hours = 0.03125 days // Price: 100.00 * 0.03125 = 3.125 - $this->assertEquals(3.13, round($cartItem->price, 2)); // Rounded due to decimal precision + $this->assertEquals(313, round($cartItem->price, 2)); // Rounded due to decimal precision } /** @test */ @@ -210,14 +210,14 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = $cart->addToCart($this->bookingProduct, 1, [], $from, $until); // Initial: 1 day = 100.00 - $this->assertEquals('100.00', $cartItem->price); + $this->assertEquals('10000', $cartItem->price); // Update from date to make it 30 hours (1.25 days) $newFrom = Carbon::now()->addDays(5)->setTime(6, 0, 0); $cartItem->setFromDate($newFrom); // Price should be 125.00 for 1.25 days - $this->assertEquals(125.00, $cartItem->fresh()->price); + $this->assertEquals(12500, $cartItem->fresh()->price); } /** @test */ @@ -233,14 +233,14 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = $cart->addToCart($this->bookingProduct, 1, [], $from, $until); // Initial: 0.5 days = 50.00 - $this->assertEquals('50.00', $cartItem->price); + $this->assertEquals('5000', $cartItem->price); // Update until date to make it 18 hours (0.75 days) $newUntil = Carbon::now()->addDays(6)->setTime(4, 0, 0); $cartItem->setUntilDate($newUntil); // Price should be 75.00 for 0.75 days - $this->assertEquals(75.00, $cartItem->fresh()->price); + $this->assertEquals(7500, $cartItem->fresh()->price); } /** @test */ @@ -254,7 +254,7 @@ class BookingPerMinutePricingTest extends TestCase // 64 hours = 2.6667 days (rounded) // Price: 100.00 * 2.6667 = 266.67 - $expectedPrice = round(100.00 * (64 / 24), 2); + $expectedPrice = round(10000 * (64 / 24), 0); $this->assertEquals($expectedPrice, $cartItem->price); } @@ -276,11 +276,11 @@ class BookingPerMinutePricingTest extends TestCase $until2 = Carbon::now()->addDays(10)->setTime(16, 0, 0); $item2 = $cart->addToCart($this->bookingProduct, 1, [], $from2, $until2); - $this->assertEquals('50.00', $item1->price); // 12 hours = 0.5 days - $this->assertEquals('25.00', $item2->price); // 6 hours = 0.25 days + $this->assertEquals('5000', $item1->price); // 12 hours = 0.5 days + $this->assertEquals('2500', $item2->price); // 6 hours = 0.25 days // Total cart should be 75.00 - $this->assertEquals(75.00, $cart->getTotal()); + $this->assertEquals(7500, $cart->getTotal()); } /** @test */ @@ -288,11 +288,11 @@ class BookingPerMinutePricingTest extends TestCase { // Test various odd time spans $testCases = [ - ['hours' => 1, 'expectedDays' => 1 / 24, 'expectedPrice' => 4.17], // 1 hour - ['hours' => 3, 'expectedDays' => 3 / 24, 'expectedPrice' => 12.50], // 3 hours - ['hours' => 7, 'expectedDays' => 7 / 24, 'expectedPrice' => 29.17], // 7 hours - ['hours' => 13, 'expectedDays' => 13 / 24, 'expectedPrice' => 54.17], // 13 hours - ['hours' => 25, 'expectedDays' => 25 / 24, 'expectedPrice' => 104.17], // 25 hours + ['hours' => 1, 'expectedDays' => 1 / 24, 'expectedPrice' => 417], // 1 hour + ['hours' => 3, 'expectedDays' => 3 / 24, 'expectedPrice' => 1250], // 3 hours + ['hours' => 7, 'expectedDays' => 7 / 24, 'expectedPrice' => 2917], // 7 hours + ['hours' => 13, 'expectedDays' => 13 / 24, 'expectedPrice' => 5417], // 13 hours + ['hours' => 25, 'expectedDays' => 25 / 24, 'expectedPrice' => 10417], // 25 hours ]; foreach ($testCases as $testCase) { @@ -321,9 +321,9 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 2, $from, $until); // Verify per-minute pricing is correct - $this->assertEquals('25.00', $cartItem->price); + $this->assertEquals('2500', $cartItem->price); $this->assertEquals(2, $cartItem->quantity); - $this->assertEquals(50.00, $cartItem->subtotal); + $this->assertEquals(5000, $cartItem->subtotal); // Remove item $cartItemId = $cartItem->id; @@ -334,20 +334,20 @@ class BookingPerMinutePricingTest extends TestCase // Re-add with different quantity - price calculation should be consistent $cartItem2 = Cart::addBooking($this->bookingProduct, 3, $from, $until); - $this->assertEquals('25.00', $cartItem2->price); + $this->assertEquals('2500', $cartItem2->price); $this->assertEquals(3, $cartItem2->quantity); - $this->assertEquals(75.00, $cartItem2->subtotal); + $this->assertEquals(7500, $cartItem2->subtotal); } /** @test */ public function it_calculates_price_for_half_hour_increments() { $testCases = [ - ['minutes' => 30, 'expectedPrice' => '2.08'], // 0.5 hours - ['minutes' => 90, 'expectedPrice' => '6.25'], // 1.5 hours - ['minutes' => 150, 'expectedPrice' => '10.42'], // 2.5 hours - ['minutes' => 210, 'expectedPrice' => '14.58'], // 3.5 hours - ['minutes' => 270, 'expectedPrice' => '18.75'], // 4.5 hours + ['minutes' => 30, 'expectedPrice' => '208'], // 0.5 hours + ['minutes' => 90, 'expectedPrice' => '625'], // 1.5 hours + ['minutes' => 150, 'expectedPrice' => '1042'], // 2.5 hours + ['minutes' => 210, 'expectedPrice' => '1458'], // 3.5 hours + ['minutes' => 270, 'expectedPrice' => '1875'], // 4.5 hours ]; foreach ($testCases as $testCase) { @@ -377,7 +377,7 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); $expectedDays = $hours / 24; - $expectedPrice = number_format(100 * $expectedDays, 2, '.', ''); + $expectedPrice = number_format(10000 * $expectedDays, 0, '.', ''); $this->assertEquals( $expectedPrice, @@ -406,14 +406,14 @@ class BookingPerMinutePricingTest extends TestCase // Get cart total $total = $cart->getTotal(); - $this->assertEquals(25.00, $total); + $this->assertEquals(2500, $total); // Add more quantity $cart->addToCart($this->bookingProduct, 1, [], $from, $until); $cart->refresh(); // Total should double - $this->assertEquals(50.00, $cart->getTotal()); + $this->assertEquals(5000, $cart->getTotal()); } /** @test */ @@ -426,8 +426,8 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // 7 days * $100 = $700.00 - $this->assertEquals('700.00', $cartItem->price); - $this->assertEquals(700.00, $cartItem->subtotal); + $this->assertEquals('70000', $cartItem->price); + $this->assertEquals(70000, $cartItem->subtotal); } /** @test */ @@ -439,7 +439,7 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // 7.5 hours = 0.3125 days, $100 * 0.3125 = $31.25 - $this->assertEquals('31.25', $cartItem->price); + $this->assertEquals('3125', $cartItem->price); } /** @test */ @@ -452,7 +452,7 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // 4 hours = 0.166667 days, $100 * 0.166667 = $16.67 - $this->assertEquals('16.67', $cartItem->price); + $this->assertEquals('1667', $cartItem->price); } /** @test */ @@ -465,10 +465,10 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); // 2 minutes = 0.001389 days, $100 * 0.001389 = $0.1389, rounds to $0.14 - $this->assertEquals('0.14', $cartItem->price); + $this->assertEquals('14', $cartItem->price); // Should still be less than 1 dollar - $this->assertLessThan(1.0, (float)$cartItem->price); + $this->assertLessThan(100, (float)$cartItem->price); } /** @test */ @@ -483,7 +483,7 @@ class BookingPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->bookingProduct, 1, $from, $until); $expectedDays = $minutes / 1440; - $expectedPrice = number_format(100 * $expectedDays, 2, '.', ''); + $expectedPrice = number_format(10000 * $expectedDays, 0, '.', ''); $this->assertEquals( $expectedPrice, diff --git a/tests/Feature/CartCheckoutSessionTest.php b/tests/Feature/CartCheckoutSessionTest.php index 980672a..9ab4b07 100644 --- a/tests/Feature/CartCheckoutSessionTest.php +++ b/tests/Feature/CartCheckoutSessionTest.php @@ -204,8 +204,8 @@ class CartCheckoutSessionTest extends TestCase 'cancel_url' => 'https://example.com/cancel', ]); - // Cart stores price as decimal (25.50), Stripe needs cents (2550) - $this->assertEquals(255000, $sessionParams['line_items'][0]['price_data']['unit_amount']); + // Price is stored in cents (2550), Stripe expects cents (2550) + $this->assertEquals(2550, $sessionParams['line_items'][0]['price_data']['unit_amount']); } /** @test */ @@ -252,9 +252,8 @@ class CartCheckoutSessionTest extends TestCase // The cart item should have calculated the fractional day price $cartItem = $this->cart->items->first(); - // Price should be rounded appropriately and converted to cents - $expectedCents = (int) round($cartItem->price * 100); - $this->assertEquals($expectedCents, $sessionParams['line_items'][0]['price_data']['unit_amount']); + // Price is already in cents, no conversion needed + $this->assertEquals($cartItem->price, $sessionParams['line_items'][0]['price_data']['unit_amount']); } /** @test */ diff --git a/tests/Feature/PoolPerMinutePricingTest.php b/tests/Feature/PoolPerMinutePricingTest.php index 539d623..3ddfb02 100644 --- a/tests/Feature/PoolPerMinutePricingTest.php +++ b/tests/Feature/PoolPerMinutePricingTest.php @@ -64,7 +64,7 @@ class PoolPerMinutePricingTest extends TestCase ProductPrice::factory()->create([ 'purchasable_id' => $this->singleItem1->id, 'purchasable_type' => Product::class, - 'unit_amount' => 50, // $50.00 per day + 'unit_amount' => 5000, // $50.00 per day (in cents) 'currency' => 'USD', 'is_default' => true, ]); @@ -72,7 +72,7 @@ class PoolPerMinutePricingTest extends TestCase ProductPrice::factory()->create([ 'purchasable_id' => $this->singleItem2->id, 'purchasable_type' => Product::class, - 'unit_amount' => 30, // $30.00 per day + 'unit_amount' => 3000, // $30.00 per day (in cents) 'currency' => 'USD', 'is_default' => true, ]); @@ -90,8 +90,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); // Lowest price is $30, for 0.5 days = $15.00 - $this->assertEquals(15.00, $cartItem->price); - $this->assertEquals(15.00, $cartItem->subtotal); + $this->assertEquals(1500, $cartItem->price); + $this->assertEquals(1500, $cartItem->subtotal); } /** @test */ @@ -103,8 +103,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); // Lowest price is $30, for 1.5 days = $45.00 - $this->assertEquals(45.00, $cartItem->price); - $this->assertEquals(45.00, $cartItem->subtotal); + $this->assertEquals(4500, $cartItem->price); + $this->assertEquals(4500, $cartItem->subtotal); } /** @test */ @@ -116,8 +116,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); // Lowest price is $30, for 0.25 days = $7.50 - $this->assertEquals(7.50, $cartItem->price); - $this->assertEquals(7.50, $cartItem->subtotal); + $this->assertEquals(750, $cartItem->price); + $this->assertEquals(750, $cartItem->subtotal); } /** @test */ @@ -129,7 +129,7 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); // Lowest price is $30, for 0.0625 days = $1.875 (rounds to 1.88) - $this->assertEquals(1.88, round($cartItem->price, 2)); + $this->assertEquals(188, round($cartItem->price, 2)); } /** @test */ @@ -139,7 +139,7 @@ class PoolPerMinutePricingTest extends TestCase ProductPrice::factory()->create([ 'purchasable_id' => $this->poolProduct->id, 'purchasable_type' => Product::class, - 'unit_amount' => 20, // $20.00 per day + 'unit_amount' => 2000, // $20.00 per day (in cents) 'currency' => 'USD', 'is_default' => true, ]); @@ -149,9 +149,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Direct pool price is $20, for 0.5 days = $10.00 - $this->assertEquals(10.00, $cartItem->price); - $this->assertEquals(10.00, $cartItem->subtotal); + // Direct pool price is $20.00 (2000 cents), for 0.5 days = $10.00 (1000 cents) + $this->assertEquals(1000, $cartItem->price); + $this->assertEquals(1000, $cartItem->subtotal); } /** @test */ @@ -162,10 +162,10 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 2, $from, $until); - // Lowest price is $30, for 0.25 days = $7.50 per unit - // 2 units * $7.50 = $15.00 total - $this->assertEquals(7.50, $cartItem->price); // price per unit - $this->assertEquals(15.00, $cartItem->subtotal); // total for 2 units + // Lowest price is $30.00 (3000 cents), for 0.25 days = $7.50 (750 cents) per unit + // 2 units * 750 cents = 1500 cents total + $this->assertEquals(750, $cartItem->price); // price per unit + $this->assertEquals(1500, $cartItem->subtotal); // total for 2 units } /** @test */ @@ -179,9 +179,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Highest price is $50, for 0.5 days = $25.00 - $this->assertEquals(25.00, $cartItem->price); - $this->assertEquals(25.00, $cartItem->subtotal); + // Highest price is $50.00 (5000 cents), for 0.5 days = $25.00 (2500 cents) + $this->assertEquals(2500, $cartItem->price); + $this->assertEquals(2500, $cartItem->subtotal); } /** @test */ @@ -195,9 +195,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Average price is ($50 + $30) / 2 = $40, for 0.5 days = $20.00 - $this->assertEquals(20.00, $cartItem->price); - $this->assertEquals(20.00, $cartItem->subtotal); + // Average price is (5000 + 3000) / 2 = 4000 cents ($40.00), for 0.5 days = $20.00 (2000 cents) + $this->assertEquals(2000, $cartItem->price); + $this->assertEquals(2000, $cartItem->subtotal); } /** @test */ @@ -218,13 +218,13 @@ class PoolPerMinutePricingTest extends TestCase $cartItem1 = $cart->addToCart($this->poolProduct, 1, [], $from1, $until1); $cartItem2 = $cart->addToCart($this->poolProduct, 1, [], $from2, $until2); - // First booking uses lowest pricing: $30 * 0.25 = $7.50 - $this->assertEquals('7.50', $cartItem1->price); + // First booking uses lowest pricing: 3000 cents * 0.25 = 750 cents ($7.50) + $this->assertEquals(750, $cartItem1->price); // Second booking may use next available pricing tier - $this->assertGreaterThanOrEqual(7.50, (float)$cartItem2->price); + $this->assertGreaterThanOrEqual(750, (int)$cartItem2->price); // Total should be reasonable for two 6-hour bookings - $this->assertGreaterThan(15.00, $cart->getTotal()); + $this->assertGreaterThan(1500, $cart->getTotal()); } /** @test */ @@ -236,8 +236,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 30 minutes = 0.020833 days, $30 * 0.020833 = $0.62499, rounds to $0.62 - $this->assertEquals('0.62', $cartItem->price); + // 30 minutes = 0.020833 days, 3000 cents * 0.020833 = 62.499 cents, rounds to 62 cents + $this->assertEquals(62, $cartItem->price); // 15 minutes $from2 = Carbon::now()->addDays(6)->setTime(14, 0, 0); @@ -245,8 +245,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem2 = Cart::addBooking($this->poolProduct, 1, $from2, $until2); - // 15 minutes = 0.010417 days, $30 * 0.010417 = $0.3125, rounds to $0.31 - $this->assertEquals('0.31', $cartItem2->price); + // 15 minutes = 0.010417 days, 3000 cents * 0.010417 = 31.25 cents, rounds to 31 cents + $this->assertEquals(31, $cartItem2->price); } /** @test */ @@ -267,11 +267,11 @@ class PoolPerMinutePricingTest extends TestCase $until2 = Carbon::now()->addDays(10)->setTime(16, 0, 0); $item2 = $cart->addToCart($this->poolProduct, 1, [], $from2, $until2); - // First booking: $30 * 0.5 = $15.00 - $this->assertEquals(15.00, $item1->price); + // First booking: 3000 cents * 0.5 = 1500 cents ($15.00) + $this->assertEquals(1500, $item1->price); - // Second booking: $30 * 0.25 = $7.50 (different dates, so spots available) - $this->assertEquals(7.50, $item2->price); + // Second booking: 3000 cents * 0.25 = 750 cents ($7.50) (different dates, so spots available) + $this->assertEquals(750, $item2->price); } /** @test */ @@ -282,8 +282,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest price is $30, for 0.125 days = $3.75 - $this->assertEquals(3.75, $cartItem->price); + // Lowest price is 3000 cents, for 0.125 days = 375 cents ($3.75) + $this->assertEquals(375, $cartItem->price); } /** @test */ @@ -294,9 +294,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest price is $30, for 5.5 hours (0.229167 days) = $6.875 (rounds to 6.88) - $expectedPrice = round(30.00 * (5.5 / 24), 2); - $this->assertEquals($expectedPrice, round($cartItem->price, 2)); + // Lowest price is 3000 cents, for 5.5 hours (0.229167 days) = 687.5 cents, rounds to 688 cents ($6.88) + $expectedPrice = round(3000 * (5.5 / 24)); + $this->assertEquals($expectedPrice, round($cartItem->price)); } /** @test */ @@ -308,8 +308,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest price is $30, for 2.125 days = $63.75 - $expectedPrice = 30.00 * 2.125; + // Lowest price is 3000 cents, for 2.125 days = 6375 cents ($63.75) + $expectedPrice = 3000 * 2.125; $this->assertEquals($expectedPrice, $cartItem->price); } @@ -327,7 +327,7 @@ class PoolPerMinutePricingTest extends TestCase ProductPrice::factory()->create([ 'purchasable_id' => $singleItem3->id, 'purchasable_type' => Product::class, - 'unit_amount' => 40, // $40.00 per day + 'unit_amount' => 4000, // $40.00 per day (in cents) 'currency' => 'USD', 'is_default' => true, ]); @@ -341,8 +341,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest price is still $30, for 0.25 days = $7.50 - $this->assertEquals(7.50, $cartItem->price); + // Lowest price is still 3000 cents, for 0.25 days = 750 cents ($7.50) + $this->assertEquals(750, $cartItem->price); } /** @test */ @@ -353,9 +353,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest price is $30, for exactly 1 day = $30.00 - $this->assertEquals(30.00, $cartItem->price); - $this->assertEquals(30.00, $cartItem->subtotal); + // Lowest price is 3000 cents, for exactly 1 day = 3000 cents ($30.00) + $this->assertEquals(3000, $cartItem->price); + $this->assertEquals(3000, $cartItem->subtotal); } /** @test */ @@ -371,15 +371,15 @@ class PoolPerMinutePricingTest extends TestCase ]); $cartItem = $cart->addToCart($this->poolProduct, 1, [], $from, $until); - // Initial: 1 day = $30.00 - $this->assertEquals(30.00, $cartItem->price); + // Initial: 1 day = 3000 cents ($30.00) + $this->assertEquals(3000, $cartItem->price); // Update from date to make it 30 hours (1.25 days) $newFrom = $now->copy()->addDays(5)->setTime(6, 0, 0); $cartItem->setFromDate($newFrom); - // Price should be $30 * 1.25 = $37.50 - $this->assertEquals(37.50, $cartItem->fresh()->price); + // Price should be 3000 cents * 1.25 = 3750 cents ($37.50) + $this->assertEquals(3750, $cartItem->fresh()->price); } /** @test */ @@ -390,9 +390,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 48 hours = 2 days, $30 * 2 = $60.00 - $this->assertEquals('60.00', $cartItem->price); - $this->assertEquals(60.00, $cartItem->subtotal); + // 48 hours = 2 days, 3000 cents * 2 = 6000 cents ($60.00) + $this->assertEquals(6000, $cartItem->price); + $this->assertEquals(6000, $cartItem->subtotal); } /** @test */ @@ -404,8 +404,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 8 hours = 0.333333 days, $30 * 0.333333 = $10.00 - $this->assertEquals('10.00', $cartItem->price); + // 8 hours = 0.333333 days, 3000 cents * 0.333333 = 1000 cents ($10.00) + $this->assertEquals(1000, $cartItem->price); } /** @test */ @@ -417,8 +417,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 8 hours = 0.333333 days, $30 * 0.333333 = $10.00 - $this->assertEquals('10.00', $cartItem->price); + // 8 hours = 0.333333 days, 3000 cents * 0.333333 = 1000 cents ($10.00) + $this->assertEquals(1000, $cartItem->price); } /** @test */ @@ -430,8 +430,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 165 minutes = 0.114583 days, $30 * 0.114583 = $3.4375, rounds to $3.44 - $this->assertEquals('3.44', $cartItem->price); + // 165 minutes = 0.114583 days, 3000 cents * 0.114583 = 343.75 cents, rounds to 344 cents ($3.44) + $this->assertEquals(344, $cartItem->price); } /** @test */ @@ -446,8 +446,8 @@ class PoolPerMinutePricingTest extends TestCase // 6 hours = 0.25 days, price per unit varies by pool pricing $this->assertEquals(2, $cartItem->quantity); - // Subtotal should be reasonable for 6 hours with 2 items - $this->assertGreaterThan(10.00, $cartItem->subtotal); + // Subtotal should be reasonable for 6 hours with 2 items (at least 1000 cents = $10.00) + $this->assertGreaterThan(1000, $cartItem->subtotal); } /** @test */ @@ -459,8 +459,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 48 hours = 2 days, $30 * 2 = $60.00 - $this->assertEquals('60.00', $cartItem->price); + // 48 hours = 2 days, 3000 cents * 2 = 6000 cents ($60.00) + $this->assertEquals(6000, $cartItem->price); } /** @test */ @@ -471,8 +471,9 @@ class PoolPerMinutePricingTest extends TestCase $until = Carbon::now()->addDays(5)->setTime(13, 0, 0); // 3 hours = 0.125 days $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Lowest: $30 * 0.125 = $3.75 - $this->assertEquals('3.75', $cartItem->price); + + // 3000 cents * 0.125 = 375 cents ($3.75) + $this->assertEquals(375, $cartItem->price); // Clear cart $cartItem->delete(); @@ -480,8 +481,9 @@ class PoolPerMinutePricingTest extends TestCase // Test HIGHEST $this->poolProduct->setPricingStrategy(PricingStrategy::HIGHEST); $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Highest: $50 * 0.125 = $6.25 - $this->assertEquals('6.25', $cartItem->price); + + // 5000 cents * 0.125 = 625 cents ($6.25) + $this->assertEquals(625, $cartItem->price); // Clear cart $cartItem->delete(); @@ -489,8 +491,9 @@ class PoolPerMinutePricingTest extends TestCase // Test AVERAGE $this->poolProduct->setPricingStrategy(PricingStrategy::AVERAGE); $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // Average: ($50 + $30) / 2 = $40, $40 * 0.125 = $5.00 - $this->assertEquals('5.00', $cartItem->price); + + // (5000 + 3000) / 2 * 0.125 = 4000 * 0.125 = 500 cents ($5.00) + $this->assertEquals(500, $cartItem->price); } /** @test */ @@ -502,8 +505,8 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 1 minute = 0.000694 days (minimum), $30 * 0.000694 = $0.02082, rounds to $0.02 - $this->assertEquals('0.02', $cartItem->price); + // 1 minute = 0.000694 days (minimum), 3000 cents * 0.000694 = 2.08 cents, rounds to 2 cents + $this->assertEquals(2, $cartItem->price); } /** @test */ @@ -515,9 +518,9 @@ class PoolPerMinutePricingTest extends TestCase $cartItem = Cart::addBooking($this->poolProduct, 1, $from, $until); - // 150 minutes (seconds truncated), $30 * (150/1440) = $3.125, rounds to $3.13 or $3.14 - $price = (float)$cartItem->price; - $this->assertGreaterThanOrEqual(3.12, $price); - $this->assertLessThanOrEqual(3.14, $price); + // 2.5 hours = 0.104167 days, 3000 cents * 0.104167 = 312.5 cents, rounds to 313 cents + $price = $cartItem->price; + $this->assertGreaterThanOrEqual(312, $price); + $this->assertLessThanOrEqual(314, $price); } }