diff --git a/src/Cart.php b/src/Cart.php index 09853db..e708868 100644 --- a/src/Cart.php +++ b/src/Cart.php @@ -37,6 +37,13 @@ class Cart */ private $instance; + /** + * Defines the discount percentage. + * + * @var float + */ + private $discount; + /** * Cart constructor. * @@ -47,6 +54,7 @@ class Cart { $this->session = $session; $this->events = $events; + $this->discount = 0; $this->instance(self::DEFAULT_INSTANCE); } @@ -340,6 +348,16 @@ class Cart $this->session->put($this->instance, $content); } + /** + * Set the global discount percentage for the cart + * + * @param float $discount + */ + public function setDiscount(float $discount) + { + $this->discount = $discount; + } + /** * Store an the current instance of the cart. * @@ -462,6 +480,7 @@ class Cart } $cartItem->setTaxRate(config('cart.tax')); + $cartItem->setDiscountRate( $this->discount ); return $cartItem; } diff --git a/src/CartItem.php b/src/CartItem.php index 64e2cf6..ced9138 100644 --- a/src/CartItem.php +++ b/src/CartItem.php @@ -64,6 +64,13 @@ class CartItem implements Arrayable, Jsonable */ private $taxRate = 0; + /** + * The discount rate for the cart item. + * + * @var float + */ + private $discountRate = 0; + /** * CartItem constructor. * @@ -84,11 +91,11 @@ class CartItem implements Arrayable, Jsonable throw new \InvalidArgumentException('Please supply a valid price.'); } - $this->id = $id; - $this->name = $name; - $this->price = floatval($price); - $this->options = new CartItemOptions($options); - $this->rowId = $this->generateRowId($id, $options); + $this->id = $id; + $this->name = $name; + $this->price = floatval($price); + $this->options = new CartItemOptions($options); + $this->rowId = $this->generateRowId($id, $options); } /** @@ -103,6 +110,19 @@ class CartItem implements Arrayable, Jsonable { return $this->numberFormat($this->price, $decimals, $decimalPoint, $thousandSeperator); } + + /** + * Returns the formatted price with discount applied. + * + * @param int $decimals + * @param string $decimalPoint + * @param string $thousandSeperator + * @return string + */ + public function priceTarget($decimals = null, $decimalPoint = null, $thousandSeperator = null) + { + return $this->numberFormat($this->priceTarget, $decimals, $decimalPoint, $thousandSeperator); + } /** * Returns the formatted price with TAX. @@ -171,6 +191,32 @@ class CartItem implements Arrayable, Jsonable return $this->numberFormat($this->taxTotal, $decimals, $decimalPoint, $thousandSeperator); } + /** + * Returns the formatted tax. + * + * @param int $decimals + * @param string $decimalPoint + * @param string $thousandSeperator + * @return string + */ + public function discount($decimals = null, $decimalPoint = null, $thousandSeperator = null) + { + return $this->numberFormat($this->discount, $decimals, $decimalPoint, $thousandSeperator); + } + + /** + * Returns the formatted tax. + * + * @param int $decimals + * @param string $decimalPoint + * @param string $thousandSeperator + * @return string + */ + public function discountTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null) + { + return $this->numberFormat($this->discountTotal, $decimals, $decimalPoint, $thousandSeperator); + } + /** * Set the quantity for this cart item. * @@ -242,6 +288,19 @@ class CartItem implements Arrayable, Jsonable return $this; } + /** + * Set the discount rate. + * + * @param int|float $discountRate + * @return \Gloudemans\Shoppingcart\CartItem + */ + public function setDiscountRate($discountRate) + { + $this->discountRate = $discountRate; + + return $this; + } + /** * Get an attribute from the cart item or get the associated model. * @@ -254,26 +313,38 @@ class CartItem implements Arrayable, Jsonable return $this->{$attribute}; } - if($attribute === 'priceTax') { - return $this->price + $this->tax; + if($attribute === 'discount') { + return $this->price * ($this->discountRate / 100); } - + + if($attribute === 'priceTarget') { + return $this->price - $this->discount; + } + if($attribute === 'subtotal') { - return $this->qty * $this->price; + return $this->qty * $this->priceTarget; + } + + if($attribute === 'tax') { + return $this->priceTarget * ($this->taxRate / 100); + } + + if($attribute === 'priceTax') { + return $this->priceTarget + $this->tax; } if($attribute === 'total') { return $this->qty * ($this->priceTax); } - - if($attribute === 'tax') { - return $this->price * ($this->taxRate / 100); - } if($attribute === 'taxTotal') { return $this->tax * $this->qty; } + if($attribute === 'discountTotal') { + return $this->discount * $this->qty; + } + if($attribute === 'model' && isset($this->associatedModel)) { return with(new $this->associatedModel)->find($this->id); } @@ -348,6 +419,7 @@ class CartItem implements Arrayable, Jsonable 'qty' => $this->qty, 'price' => $this->price, 'options' => $this->options->toArray(), + 'discount' => $this->discount, 'tax' => $this->tax, 'subtotal' => $this->subtotal ]; diff --git a/tests/CartItemTest.php b/tests/CartItemTest.php index 9688451..b1ea046 100644 --- a/tests/CartItemTest.php +++ b/tests/CartItemTest.php @@ -37,6 +37,7 @@ class CartItemTest extends TestCase ], 'tax' => 0, 'subtotal' => 20.00, + 'discount' => 0.0 ], $cartItem->toArray()); } @@ -48,7 +49,7 @@ class CartItemTest extends TestCase $this->assertJson($cartItem->toJson()); - $json = '{"rowId":"07d5da5550494c62daf9993cf954303f","id":1,"name":"Some item","qty":2,"price":10,"options":{"size":"XL","color":"red"},"tax":0,"subtotal":20}'; + $json = '{"rowId":"07d5da5550494c62daf9993cf954303f","id":1,"name":"Some item","qty":2,"price":10,"options":{"size":"XL","color":"red"},"discount":0,"tax":0,"subtotal":20}'; $this->assertEquals($json, $cartItem->toJson()); } diff --git a/tests/CartTest.php b/tests/CartTest.php index 775e4a8..2b3d6ca 100644 --- a/tests/CartTest.php +++ b/tests/CartTest.php @@ -488,6 +488,7 @@ class CartTest extends TestCase 'tax' => 2.10, 'subtotal' => 10.0, 'options' => [], + 'discount' => 0.0 ], '370d08585360f5c568b18d1f2e4ca1df' => [ 'rowId' => '370d08585360f5c568b18d1f2e4ca1df', @@ -498,6 +499,7 @@ class CartTest extends TestCase 'tax' => 2.10, 'subtotal' => 10.0, 'options' => [], + 'discount' => 0.0 ] ], $content->toArray()); } @@ -913,7 +915,7 @@ class CartTest extends TestCase $user = Mockery::mock(Authenticatable::class); - event(new Logout($user)); + event(new Logout(\Auth::guard('web'), $user)); } /**