From b102dd2356736ec071b17d347b83d1e60e15b20a Mon Sep 17 00:00:00 2001 From: Joel Male Date: Mon, 19 Aug 2024 10:35:54 +1000 Subject: [PATCH] 1.0.3 --- README.md | 8 ++ composer.json | 4 +- src/Cart.php | 63 +++++------ tests/Unit/CartConditionsTest.php | 170 ++++++++++++++++++------------ tests/Unit/CartTest.php | 2 - 5 files changed, 146 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index 6247bf8..f19bf5d 100644 --- a/README.md +++ b/README.md @@ -499,10 +499,18 @@ #### Add condition to existing Item on the cart: **Cart::addItemCondition($produ ### Clearing Cart Conditions: **Cart::clearCartConditions()** +This clears all cart level conditions, and does not affect item level conditions. + ```php Cart::clearCartConditions() ``` +If you wish to clear all conditions from all items and the cart, use **Cart::clearAllConditions()** + +```php +Cart::clearAllConditions() +``` + ### Remove a specific cart condtion: **Cart::removeCartCondition($conditionName)** ```php diff --git a/composer.json b/composer.json index 9f7f388..c15c619 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "wearepixel/laravel-cart", - "version": "1.0.2", + "version": "1.0.3", "description": "A cart implementation for Laravel", "keywords": [ "laravel", @@ -19,7 +19,7 @@ } ], "require": { - "php": ">=8.0", + "php": ">=8.1", "illuminate/support": "^9.0|^10.0|^11.0", "illuminate/validation": "^9.0|^10.0|^11.0", "illuminate/translation": "^9.0|^10.0|^11.0" diff --git a/src/Cart.php b/src/Cart.php index 6728576..a4a2b04 100644 --- a/src/Cart.php +++ b/src/Cart.php @@ -131,20 +131,20 @@ public function has($itemId) * add item to the cart, it can be an array or multi dimensional array * * @param string|array $id - * @param string $name - * @param float $price - * @param int $quantity - * @param array $attributes - * @param CartCondition|array $conditions - * @param string $associatedModel * @return $this * * @throws InvalidItemException */ - public function add($id, $name = null, $price = null, $quantity = null, $attributes = [], $conditions = [], $associatedModel = null) - { - // if the first argument is an array, - // we will need to call add again + public function add( + string|int|array $id, + ?string $name = null, + ?float $price = null, + int|float|null $quantity = null, + array $attributes = [], + array|CartCondition $conditions = [], + ?string $associatedModel = null + ): self { + // check if its an array of items if (is_array($id)) { // the first argument is an array, now we will need to check if it is a multi dimensional // array, if so, we will iterate through each item and call add again @@ -192,10 +192,10 @@ public function add($id, $name = null, $price = null, $quantity = null, $attribu $item = $this->validate($data); // get the cart - $cart = $this->getContent(); + $inCart = $this->get($id); // if the item is already in the cart we will just update it - if ($cart->has($id)) { + if ($inCart) { $this->update($id, $item); } else { $this->addItem($id, $item); @@ -207,15 +207,9 @@ public function add($id, $name = null, $price = null, $quantity = null, $attribu } /** - * update a cart - * - * @param array $data - * - * the $data will be an associative array, you don't need to pass all the data, only the key value - * of the item you want to update on it - * @return bool + * Update a cart item with whatever data is passed in */ - public function update($id, $data) + public function update(int|string $id, array $data): bool { if ($this->fireEvent('updating', $data) === false) { return false; @@ -344,14 +338,11 @@ public function clear() } /** - * add a condition on the cart - * - * @param CartCondition|array $condition - * @return $this + * Adds a condition to the cart * * @throws InvalidConditionException */ - public function condition(CartCondition $condition) + public function condition(array|CartCondition $condition): self { if (is_array($condition)) { foreach ($condition as $c) { @@ -524,13 +515,9 @@ public function clearItemConditions($itemId) } /** - * clears all conditions on a cart, - * this does not remove conditions that has been added specifically to an item/product. - * If you wish to remove a specific condition to a product, you may use the method: removeItemCondition($itemId, $conditionName) - * - * @return void + * Clear cart conditions (this does not clear item conditions) */ - public function clearCartConditions() + public function clearCartConditions(): void { $this->session->put( $this->sessionKeyCartConditions, @@ -538,6 +525,20 @@ public function clearCartConditions() ); } + /** + * Clear all conditions from all items and the cart + */ + public function clearAllConditions(): void + { + $cart = $this->getContent(); + + $cart->each(function ($item) { + $this->clearItemConditions($item->id); + }); + + $this->clearCartConditions(); + } + /** * get cart sub total without conditions * diff --git a/tests/Unit/CartConditionsTest.php b/tests/Unit/CartConditionsTest.php index 55ffc78..6553623 100644 --- a/tests/Unit/CartConditionsTest.php +++ b/tests/Unit/CartConditionsTest.php @@ -791,6 +791,40 @@ expect($couponDiscount->getCalculatedValue())->toEqual(200.0, 'Coupon Discount value should be 200.0'); expect($giftCard->getCalculatedValue())->toEqual(0, 'Gift Card value should be 0'); }); + + test('can be cleared', function () { + $siteWideDiscount = new CartCondition([ + 'name' => 'Site Wide Discount', + 'type' => 'discount', + 'target' => 'total', + 'value' => '-5%', + ]); + + $giftCard = new CartCondition([ + 'name' => 'Gift Card', + 'type' => 'gift_card', + 'target' => 'total', + 'value' => '-25', + ]); + + $item = [ + 'id' => 1, + 'name' => 'Backpack', + 'price' => 168.72, + 'quantity' => 1, + 'attributes' => [], + ]; + + $this->cart->add($item); + + $this->cart->condition([$siteWideDiscount, $giftCard]); + + expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions'); + + $this->cart->clearCartConditions(); + + expect($this->cart->getConditions()->count())->toEqual(0, 'Cart should have no conditions now'); + }); }); describe('item level conditions', function () { @@ -890,113 +924,72 @@ expect($this->cart->getTotal())->toEqual(411.77, 'Cart total with 1 item should be 411.77'); }); - test('add item condition', function () { + test('can add item condition to an item that already has conditions', function () { $items = [ [ - 'id' => 456, - 'name' => 'Sample Item 1', + 'id' => 1, + 'name' => 'Children\'s Bookcase', 'price' => 67.99, 'quantity' => 1, 'attributes' => [], ], - [ - 'id' => 568, - 'name' => 'Sample Item 2', - 'price' => 69.25, - 'quantity' => 1, - 'attributes' => [], - ], - [ - 'id' => 856, - 'name' => 'Sample Item 3', - 'price' => 50.25, - 'quantity' => 1, - 'attributes' => [], - ], ]; $this->cart->add($items); - $itemCondition2 = new CartCondition([ - 'name' => 'Item Gift Pack 25.00', + $discount = new CartCondition([ + 'name' => '$25 Off', 'type' => 'promo', 'value' => '-25', ]); - $coupon101 = new CartCondition([ - 'name' => 'COUPON 101', + + $childrenDiscount = new CartCondition([ + 'name' => '5% Off Childrens Items', 'type' => 'coupon', 'value' => '-5%', ]); $item = [ - 'id' => 456, - 'name' => 'Sample Item 1', - 'price' => 100, + 'id' => 2, + 'name' => 'Children\'s Pack of Books', + 'price' => 31.22, 'quantity' => 1, 'attributes' => [], - 'conditions' => [$itemCondition2], + 'conditions' => [$discount], ]; $this->cart->add($item); // let's prove first we have 1 condition on this item - expect($this->cart->get($item['id'])['conditions'])->toHaveCount(1, 'Item should have 1 condition'); + expect($this->cart->get(2)['conditions'])->toHaveCount(1, 'Item should have 1 condition'); // now let's insert a condition on an existing item on the cart - $this->cart->addItemCondition($item['id'], $coupon101); + $this->cart->addItemCondition(2, $childrenDiscount); - expect($this->cart->get($item['id'])['conditions'])->toHaveCount(2, 'Item should have 2 conditions'); + expect($this->cart->get(2)['conditions'])->toHaveCount(2, 'Item should have 2 conditions'); }); - test('add item condition restrict negative price', function () { - $items = [ - [ - 'id' => 456, - 'name' => 'Sample Item 1', - 'price' => 67.99, - 'quantity' => 1, - 'attributes' => [], - ], - [ - 'id' => 568, - 'name' => 'Sample Item 2', - 'price' => 69.25, - 'quantity' => 1, - 'attributes' => [], - ], - [ - 'id' => 856, - 'name' => 'Sample Item 3', - 'price' => 50.25, - 'quantity' => 1, - 'attributes' => [], - ], + test('will not take the price below 0', function () { + $item = [ + 'id' => 1, + 'name' => 'Picture Frame', + 'price' => 22.50, + 'quantity' => 1, + 'attributes' => [], ]; - $this->cart->add($items); - $condition = new CartCondition([ - 'name' => 'Substract amount but prevent negative value', + 'name' => '$25 Discount', 'type' => 'promo', 'value' => '-25', ]); - $item = [ - 'id' => 789, - 'name' => 'Sample Item 1', - 'price' => 20, - 'quantity' => 1, - 'attributes' => [], - 'conditions' => [ - $condition, - ], - ]; - $this->cart->add($item); + $this->cart->addItemCondition(1, $condition); // Since the product price is 20 and the condition reduces it by 25, // check that the item's price has been prevented from dropping below zero. - expect($this->cart->get($item['id'])->getPriceSumWithConditions())->toEqual(0.00, "The item's price should be prevented from going below zero."); + expect($this->cart->get(1)->getPriceSumWithConditions())->toEqual(0.00, "The item's price should be prevented from going below zero."); }); // test('get cart condition by condition name', function () { @@ -1475,3 +1468,48 @@ // }); }); + +describe('conditions', function () { + test('can be completely cleared', function () { + $siteWideDiscount = new CartCondition([ + 'name' => 'Site Wide Discount', + 'type' => 'discount', + 'target' => 'total', + 'value' => '-5%', + ]); + + $giftCard = new CartCondition([ + 'name' => 'Gift Card', + 'type' => 'gift_card', + 'target' => 'total', + 'value' => '-25', + ]); + + $itemCondition = new CartCondition([ + 'name' => 'Item Discount', + 'type' => 'discount', + 'value' => '-5%', + ]); + + $item = [ + 'id' => 1, + 'name' => 'Backpack', + 'price' => 168.72, + 'quantity' => 1, + 'attributes' => [], + 'conditions' => [$itemCondition], + ]; + + $this->cart->add($item); + + $this->cart->condition([$siteWideDiscount, $giftCard]); + + expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions'); + expect($this->cart->get(1)['conditions'])->toHaveCount(1, 'Cart should have one condition'); + + $this->cart->clearAllConditions(); + + expect($this->cart->getConditions()->count())->toEqual(0, 'Cart should have no conditions now'); + expect($this->cart->get(1)['conditions'])->toHaveCount(0, 'Cart items should have no conditions now'); + }); +}); diff --git a/tests/Unit/CartTest.php b/tests/Unit/CartTest.php index c9ff6e3..5b4a759 100644 --- a/tests/Unit/CartTest.php +++ b/tests/Unit/CartTest.php @@ -477,8 +477,6 @@ }); test('sub total when item quantity is updated by reduced', function () { - // $this->cart->setConfig(['format_numbers' => true, 'decimals' => 2, 'dec_point' => '.', 'thousands_sep' => ',']); - $items = [ [ 'id' => 456,