Skip to content

Commit

Permalink
Merge pull request #59 from Sartoric/fix-cart-total-rounding-issue
Browse files Browse the repository at this point in the history
Fix cart total rounding issue
  • Loading branch information
bumbummen99 authored Feb 1, 2020
2 parents 3a4b79d + 0874bb1 commit 97e021f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 19 deletions.
34 changes: 30 additions & 4 deletions src/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ public function subtotal($decimals = null, $decimalPoint = null, $thousandSepera
}

/**
* Get the subtotal (total - tax) of the items in the cart.
* Get the discount of the items in the cart.
*
* @return float
*/
Expand All @@ -387,7 +387,7 @@ public function discountFloat()
}

/**
* Get the subtotal (total - tax) of the items in the cart as formatted string.
* Get the discount of the items in the cart as formatted string.
*
* @param int $decimals
* @param string $decimalPoint
Expand All @@ -401,7 +401,7 @@ public function discount($decimals = null, $decimalPoint = null, $thousandSepera
}

/**
* Get the subtotal (total - tax) of the items in the cart.
* Get the price of the items in the cart (not rounded).
*
* @return float
*/
Expand All @@ -413,7 +413,7 @@ public function initialFloat()
}

/**
* Get the subtotal (total - tax) of the items in the cart as formatted string.
* Get the price of the items in the cart as formatted string.
*
* @param int $decimals
* @param string $decimalPoint
Expand All @@ -426,6 +426,32 @@ public function initial($decimals = null, $decimalPoint = null, $thousandSeperat
return $this->numberFormat($this->initialFloat(), $decimals, $decimalPoint, $thousandSeperator);
}

/**
* Get the price of the items in the cart (previously rounded).
*
* @return float
*/
public function priceTotalFloat()
{
return $this->getContent()->reduce(function ($initial, CartItem $cartItem) {
return $initial + $cartItem->priceTotal;
}, 0);
}

/**
* Get the price of the items in the cart as formatted string.
*
* @param int $decimals
* @param string $decimalPoint
* @param string $thousandSeperator
*
* @return string
*/
public function priceTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->priceTotalFloat(), $decimals, $decimalPoint, $thousandSeperator);
}

/**
* Get the total weight of the items in the cart.
*
Expand Down
41 changes: 29 additions & 12 deletions src/CartItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,20 @@ public function discountTotal($decimals = null, $decimalPoint = null, $thousandS
return $this->numberFormat($this->discountTotal, $decimals, $decimalPoint, $thousandSeperator);
}

/**
* Returns the formatted total price for this cart item.
*
* @param int $decimals
* @param string $decimalPoint
* @param string $thousandSeperator
*
* @return string
*/
public function priceTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->priceTotal, $decimals, $decimalPoint, $thousandSeperator);
}

/**
* Set the quantity for this cart item.
*
Expand Down Expand Up @@ -354,26 +368,29 @@ public function __get($attribute)
if (property_exists($this, $attribute)) {
return $this->{$attribute};
}
$decimals = config('cart.format.decimals', 2);

switch ($attribute) {
case 'discount':
return $this->price * ($this->discountRate / 100);
case 'priceTarget':
return $this->price - $this->discount;
case 'subtotal':
return $this->priceTarget * $this->qty;
case 'tax':
return $this->priceTarget * ($this->taxRate / 100);
return round($this->priceTarget * ($this->taxRate / 100), $decimals);
case 'priceTax':
return $this->priceTarget + $this->tax;
case 'total':
return $this->priceTax * $this->qty;
case 'taxTotal':
return $this->tax * $this->qty;
return round($this->priceTarget + $this->tax, $decimals);
case 'discountTotal':
return $this->discount * $this->qty;
return round($this->discount * $this->qty, $decimals);
case 'weightTotal':
return $this->weight * $this->qty;
return round($this->weight * $this->qty, $decimals);
case 'priceTotal':
return round($this->price * $this->qty, $decimals);
case 'subtotal':
return round($this->priceTotal - $this->discountTotal, $decimals);
case 'priceTarget':
return round(($this->priceTotal - $this->discountTotal) / $this->qty, $decimals);
case 'taxTotal':
return round($this->subtotal * ($this->taxRate / 100), $decimals);
case 'total':
return round($this->subtotal + $this->taxTotal, $decimals);

case 'model':
if (isset($this->associatedModel)) {
Expand Down
28 changes: 25 additions & 3 deletions tests/CartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ public function can_change_discount_globally()
}

/** @test */
public function cart_hast_no_rounding_errors()
public function cart_has_no_rounding_errors()
{
$cart = $this->getCart();

Expand Down Expand Up @@ -1309,6 +1309,26 @@ public function it_can_merge_dispatching_add_events()
});
}

/** @test */
public function it_use_correctly_rounded_values_for_totals_and_cart_summary()
{
$this->setConfigFormat(2, ',', '');

$cart = $this->getCartDiscount(6);

$cartItem = $cart->add(new BuyableProduct(1, 'First item', 0.18929), 1000);
$cart->add(new BuyableProduct(2, 'Second item', 4.41632), 5);
$cart->add(new BuyableProduct(3, 'Third item', 0.37995), 25);

$cart->setGlobalTax(22);

// check total
$this->assertEquals('253,29', $cart->total());

// check that the sum of cart subvalues matches the total (in order to avoid cart summary to looks wrong)
$this->assertEquals($cart->totalFloat(), $cart->subtotalFloat() + $cart->taxFloat());
}

/**
* Get an instance of the cart.
*
Expand All @@ -1325,12 +1345,14 @@ private function getCart()
/**
* Get an instance of the cart with discount.
*
* @param int $discount
*
* @return \Gloudemans\Shoppingcart\Cart
*/
private function getCartDiscount($discount = 0)
private function getCartDiscount($discount = 50)
{
$cart = $this->getCart();
$cart->setGlobalDiscount(50);
$cart->setGlobalDiscount($discount);

return $cart;
}
Expand Down

0 comments on commit 97e021f

Please sign in to comment.