From 03d08f17a3705ab1e32f8c21df77a7ba420ed70e Mon Sep 17 00:00:00 2001 From: Nafies Luthfi Date: Sun, 9 Apr 2017 10:47:24 +0800 Subject: [PATCH] Added Cart Draft Item class with Product as its dependency --- app/Cart/CartCollection.php | 15 +++---- app/Cart/Item.php | 45 +++++++++++++++++++ app/Cart/TransactionDraft.php | 38 ++++++++++++++++ app/Product.php | 18 ++++++++ .../2017_04_09_013901_create_products_table.php | 31 +++++++++++++ tests/Unit/CartCollectionTest.php | 52 ++++++++++++++++++++++ tests/Unit/Integration/ProductTest.php | 36 +++++++++++++++ 7 files changed, 227 insertions(+), 8 deletions(-) create mode 100644 app/Cart/Item.php create mode 100644 app/Product.php create mode 100644 database/migrations/2017_04_09_013901_create_products_table.php create mode 100644 tests/Unit/Integration/ProductTest.php diff --git a/app/Cart/CartCollection.php b/app/Cart/CartCollection.php index 5763431..f118041 100644 --- a/app/Cart/CartCollection.php +++ b/app/Cart/CartCollection.php @@ -2,6 +2,7 @@ namespace App\Cart; +use App\Product; use Illuminate\Support\Collection; /** @@ -98,28 +99,26 @@ class CartCollection $this->session->remove($this->instance); } - public function addProductToDraft($draftKey, $item) + public function addItemToDraft($draftKey, Item $item) { $content = $this->getContent(); - $content[$draftKey]->addProduct($item); - $content[$draftKey] = $this->updateDraft($content[$draftKey]); + $content[$draftKey]->addItem($item); $this->session->put($this->instance, $content); } - public function updateDraftProduct($draftKey, $itemKey, $newProductData) + public function updateDraftItem($draftKey, $itemKey, $newItemData) { $content = $this->getContent(); - $content[$draftKey]->updateProduct($itemKey, $newProductData); - $content[$draftKey] = $this->updateDraft($content[$draftKey]); + $content[$draftKey]->updateItem($itemKey, $newItemData); $this->session->put($this->instance, $content); } - public function removeProductFromDraft($draftKey, $itemKey) + public function removeItemFromDraft($draftKey, $itemKey) { $content = $this->getContent(); - $content[$draftKey]->removeProduct($itemKey); + $content[$draftKey]->removeItem($itemKey); $this->session->put($this->instance, $content); } diff --git a/app/Cart/Item.php b/app/Cart/Item.php new file mode 100644 index 0000000..6107098 --- /dev/null +++ b/app/Cart/Item.php @@ -0,0 +1,45 @@ +id = $product->id; + $this->product = $product; + $this->qty = $qty; + $this->price = $product->getPrice(); + $this->subtotal = $product->getPrice() * $qty; + } + + public function updateAttribute(array $newItemData) + { + if (isset($newItemData['qty'])) { + $this->qty = $newItemData['qty']; + $this->subtotal = $this->price * $this->qty; + } + + if (isset($newItemData['item_discount'])) { + $this->item_discount = $newItemData['item_discount']; + $this->item_discount_subtotal = $this->item_discount * $this->qty; + $this->subtotal = $this->subtotal - $this->item_discount_subtotal; + } + + return $this; + } +} \ No newline at end of file diff --git a/app/Cart/TransactionDraft.php b/app/Cart/TransactionDraft.php index 7d33cf0..831da8a 100644 --- a/app/Cart/TransactionDraft.php +++ b/app/Cart/TransactionDraft.php @@ -2,11 +2,15 @@ namespace App\Cart; +use App\Product; + /** * Transaction Draft Interface */ abstract class TransactionDraft { + public $items = []; + public function toArray() { return [ @@ -21,4 +25,38 @@ abstract class TransactionDraft 'remark' => '', ]; } + + public function items() + { + return collect($this->items); + } + + public function addItem(Item $item) + { + $this->items[] = $item; + + return $item->product; + } + + public function removeItem($itemKey) + { + unset($this->items[$itemKey]); + } + + public function getTotal() + { + return $this->items()->sum('subtotal'); + } + + public function updateItem($itemKey, $newItemData) + { + if (!isset($this->items[$itemKey])) + return null; + + $item = $this->items[$itemKey]; + + $this->items[$itemKey] = $item->updateAttribute($newItemData); + + return $item; + } } \ No newline at end of file diff --git a/app/Product.php b/app/Product.php new file mode 100644 index 0000000..873e58c --- /dev/null +++ b/app/Product.php @@ -0,0 +1,18 @@ +credit_price; + + return $this->cash_price; + } +} diff --git a/database/migrations/2017_04_09_013901_create_products_table.php b/database/migrations/2017_04_09_013901_create_products_table.php new file mode 100644 index 0000000..ec0ee65 --- /dev/null +++ b/database/migrations/2017_04_09_013901_create_products_table.php @@ -0,0 +1,31 @@ +increments('id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('products'); + } +} diff --git a/tests/Unit/CartCollectionTest.php b/tests/Unit/CartCollectionTest.php index 5f22add..b96511c 100644 --- a/tests/Unit/CartCollectionTest.php +++ b/tests/Unit/CartCollectionTest.php @@ -5,6 +5,8 @@ namespace Tests\Unit; use App\Cart\CartCollection; use App\Cart\CashDraft; use App\Cart\CreditDraft; +use App\Cart\Item; +use App\Product; use Tests\TestCase; class CartCollectionTest extends TestCase @@ -145,4 +147,54 @@ class CartCollectionTest extends TestCase $this->assertArrayHasKey('creator_id', $draft->toArray()); $this->assertArrayHasKey('remark', $draft->toArray()); } + + /** @test */ + public function it_can_add_product_to_draft() + { + $cart = new CartCollection; + + $draft = $cart->add(new CashDraft); + $count = 2; + $item = new Item(new Product(['cash_price' => 1000]), $count); + + $cart->addItemToDraft($draft->draftKey, $item); + $this->assertEquals(2000, $draft->getTotal()); + } + + /** @test */ + public function it_can_remove_item_from_draft() + { + $cart = new CartCollection; + + $draft = $cart->add(new CashDraft); + $item = new Item(new Product(['cash_price' => 1000]), 3); + + $cart->addItemToDraft($draft->draftKey, $item); + $this->assertCount(1, $draft->items()); + $cart->removeItemFromDraft($draft->draftKey, 0); + $this->assertCount(0, $draft->items()); + $this->assertEquals(0, $draft->getTotal()); + } + + /** @test */ + public function it_can_update_an_item_of_draft() + { + $cart = new CartCollection; + + $draft = $cart->add(new CashDraft); + $item = new Item(new Product(['cash_price' => 1100]), 3); + + $cart->addItemToDraft($draft->draftKey, $item); + $this->assertCount(1, $draft->items()); + $this->assertEquals(3300, $draft->getTotal()); + + $newItemData = [ + 'qty' => 2, + 'item_discount' => 100, + ]; + + $cart->updateDraftItem($draft->draftKey, 0, $newItemData); + $this->assertEquals(2000, $draft->getTotal()); + } + } diff --git a/tests/Unit/Integration/ProductTest.php b/tests/Unit/Integration/ProductTest.php new file mode 100644 index 0000000..ac8c89a --- /dev/null +++ b/tests/Unit/Integration/ProductTest.php @@ -0,0 +1,36 @@ + 3000]); + + $this->assertEquals(3000, $product->getPrice()); + } + + /** @test */ + public function product_get_price_method_default_to_cash_price() + { + $product = new Product(['cash_price' => 3000]); + + $this->assertEquals($product->cash_price, $product->getPrice()); + } + + /** @test */ + public function product_get_price_can_also_returns_credit_price_of_product() + { + $product = new Product(['cash_price' => 2000, 'credit_price' => 3000]); + + $this->assertEquals($product->credit_price, $product->getPrice('credit')); + $this->assertEquals(3000, $product->getPrice('credit')); + } +}