Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mattias-persson committed Jul 31, 2019
1 parent 29509cc commit 547a6ce
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 166 deletions.
92 changes: 6 additions & 86 deletions src/Cart/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class Cart implements CartContract
{
protected $driver;
public $driver;
protected $formatter;
protected $pendingItem;

Expand Down Expand Up @@ -45,87 +45,9 @@ public function get() : array
];
}

public function add(Shoppable $shoppable)
public function add(Shoppable $shoppable) : CartItemFactory
{
$this->pendingItem = new CartItem($shoppable);

return $this;
}

public function quantity($quantity)
{
if ($this->pendingItem) {
$this->pendingItem->quantity = $quantity;
}

return $this;
}

public function options(array $options)
{
if ($this->pendingItem) {
$this->pendingItem->options = $options;
}

return $this;
}

public function subItems(array $subItems)
{
if ($this->pendingItem) {
// Only add the items that have a valid shoppable.
$this->pendingItem->addSubItems(collect($subItems)->filter(function ($subItem) {
return $subItem['shoppable'] instanceof Shoppable;
}));
}

return $this;
}

public function overridePrice($price)
{
if ($this->pendingItem) {
$this->pendingItem->price = $price;
}

return $this;
}

public function save()
{
if (! $this->pendingItem) {
return;
}

$items = $this->getAllItems();

// Find already added items that are identical to current selection.
$identicals = $items->filter(function (CartItem $row) {
return $row->isIdenticalTo($this->pendingItem);
});

// If an identical item already exists in the cart, add to it's quantity.
// Otherwise, push it.
if ($identicals->count() > 0) {
$item = $items->where('id', $identicals->first()->id)->first();
$item->quantity += $this->pendingItem->quantity;

$event = 'updated';
} else {
$items->push($item = $this->pendingItem);

$event = 'added';
}

$item->refreshPrice();

$this->driver->persist($items);

Event::fire('shopr.cart.items.'.$event, $item);

$this->pendingItem = null;

return $item;
return new CartItemFactory($shoppable, $this);
}

/**
Expand Down Expand Up @@ -277,18 +199,16 @@ public function addDiscount(Shoppable $coupon)

/**
* Iterates all the current items in the cart and returns true if one of them is
* a discount coupon matching the given code. If no code is provided, it will return false on any
* discount coupon.
* a discount coupon matching the given code.
* If no code is provided, it will return true on any discount coupon.
*
* @param string $code
* @return bool
*/
public function hasDiscount($code = null) : bool
{
foreach ($this->discounts() as $item) {
if (! $code) {
return true;
} elseif ($item->shoppable->getTitle() === $code) {
if (! $code || $item->shoppable->getTitle() === $code) {
return true;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Cart/CartItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public function addSubItems(Collection $subItems)

$item->quantity = $this->quantity;
$item->price = $price;
$item->refreshPrice();

if ($options) {
$item->options = $options;
Expand Down
87 changes: 87 additions & 0 deletions src/Cart/CartItemFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace Happypixels\Shopr\Cart;

use Happypixels\Shopr\Contracts\Cart;
use Illuminate\Support\Facades\Event;
use Happypixels\Shopr\Contracts\Shoppable;

class CartItemFactory
{
protected $item;
protected $cart;

public function __construct(Shoppable $shoppable, Cart $cart)
{
$this->item = new CartItem($shoppable);
$this->cart = $cart;
}

public function quantity($quantity)
{
$this->item->quantity = $quantity;

return $this;
}

public function options(array $options)
{
$this->item->options = $options;

return $this;
}

public function subItems(array $subItems)
{
// Only add the items that have a valid shoppable.
$this->item->addSubItems(collect($subItems)->filter(function ($subItem) {
return $subItem['shoppable'] instanceof Shoppable;
}));

return $this;
}

public function overridePrice($price)
{
$this->item->price = $price;

return $this;
}

public function save()
{
if (! $this->item) {
return;
}

$items = $this->cart->getAllItems();

// Find already added items that are identical to current selection.
$identicals = $items->filter(function (CartItem $row) {
return $row->isIdenticalTo($this->item);
});

// If an identical item already exists in the cart, add to it's quantity.
// Otherwise, push it.
if ($identicals->count() > 0) {
$item = $items->where('id', $identicals->first()->id)->first();
$item->quantity += $this->item->quantity;

$event = 'updated';
} else {
$items->push($item = $this->item);

$event = 'added';
}

$item->refreshPrice();

$this->cart->driver->persist($items);

Event::fire('shopr.cart.items.'.$event, $item);

$this->item = null;

return $item;
}
}
1 change: 0 additions & 1 deletion src/Cart/Drivers/SessionCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Happypixels\Shopr\Cart\Drivers;

use Happypixels\Shopr\Cart\Cart;
use Illuminate\Support\Facades\Session;
use Happypixels\Shopr\Contracts\CartDriver;

Expand Down
14 changes: 3 additions & 11 deletions src/Contracts/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Happypixels\Shopr\Contracts;

use Happypixels\Shopr\Cart\CartItemFactory;

interface Cart
{
public function get() : array;
Expand All @@ -12,17 +14,7 @@ public function clear();

// public function find(string $id) : self;

public function add(Shoppable $shoppable);

public function quantity($quantity);

// public function withOptions(array $options) : self;

// public function withSubItems(array $subItems) : self;

// public function overridePrice($price) : self;

public function save();
public function add(Shoppable $shoppable) : CartItemFactory;

// public function update(array $data);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php

namespace Happypixels\Shopr\Tests\Feature\Cart;
namespace Happypixels\Shopr\Tests\REST\Cart;

use Happypixels\Shopr\Facades\Cart;
use Happypixels\Shopr\Tests\TestCase;

class CartControllerTest extends TestCase
class CartHttpTest extends TestCase
{
/** @test */
public function cart_summary()
Expand Down
1 change: 0 additions & 1 deletion tests/Unit/Cart/AddCartItemUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Happypixels\Shopr\Tests\Unit\Cart;

#use Happypixels\Shopr\Cart\Cart;
use Happypixels\Shopr\Facades\Cart;
use Happypixels\Shopr\Cart\CartItem;
use Happypixels\Shopr\Tests\TestCase;
Expand Down
37 changes: 14 additions & 23 deletions tests/Unit/Cart/AddDiscountCouponUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Happypixels\Shopr\Tests\Unit\Cart;

use Happypixels\Shopr\Cart\Cart;
use Happypixels\Shopr\Facades\Cart;
use Happypixels\Shopr\Tests\TestCase;
use Illuminate\Support\Facades\Event;
use Happypixels\Shopr\Models\DiscountCoupon;
Expand All @@ -13,44 +13,44 @@ class AddDiscountCouponUnitTest extends TestCase
/** @test */
public function it_returns_false_if_model_is_not_a_discount()
{
$shoppable = factory(TestShoppable::class)->create();

$this->assertFalse(app(Cart::class)->addDiscount($shoppable));
$this->assertFalse(Cart::addDiscount(factory(TestShoppable::class)->create()));
$this->assertFalse(Cart::hasDiscount());
}

/** @test */
public function it_calculates_the_total_value_when_not_fixed()
{
$discount = factory(DiscountCoupon::class)->create(['is_fixed' => false, 'value' => 50]);
$cart = $this->addCartItem();

Cart::add(TestShoppable::first())->overridePrice(500)->quantity(3)->save();
$item = Cart::addDiscount($discount);

// 1500 / 2 = 750.
$item = $cart->addDiscount($discount);
$this->assertEquals(-750, $item->total());
$this->assertEquals(750, $cart->total());
$this->assertEquals(750, Cart::total());
}

/** @test */
public function it_applies_the_given_value_when_fixed()
{
$discount = factory(DiscountCoupon::class)->create(['is_fixed' => true, 'value' => 300]);
$cart = $this->addCartItem();
Cart::add(TestShoppable::first())->overridePrice(500)->quantity(3)->save();
$item = Cart::addDiscount($discount);

// 1500 - 300 = 1200.
$item = $cart->addDiscount($discount);
$this->assertEquals(-300, $item->total());
$this->assertEquals(1200, $cart->total());
$this->assertEquals(1200, Cart::total());
}

/** @test */
public function it_fires_event()
{
$discount = factory(DiscountCoupon::class)->create(['is_fixed' => true, 'value' => 300]);
$cart = $this->addCartItem();
Cart::add(TestShoppable::first())->overridePrice(500)->quantity(3)->save();

Event::fake();

$item = $cart->addDiscount($discount);
$item = Cart::addDiscount($discount);

// The first time the added event is fired.
Event::assertDispatched('shopr.cart.discounts.added', function ($event, $data) use ($item) {
Expand All @@ -64,21 +64,12 @@ public function it_fires_event()
public function it_increments_the_coupon_uses()
{
$discount = factory(DiscountCoupon::class)->create(['is_fixed' => true, 'value' => 300]);
$cart = $this->addCartItem();
Cart::add(TestShoppable::first())->overridePrice(500)->quantity(3)->save();

$this->assertEquals(0, $discount->uses);

$cart->addDiscount($discount);
Cart::addDiscount($discount);

$this->assertEquals(1, $discount->uses);
}

public function addCartItem()
{
$cart = app(Cart::class);
$model = factory(TestShoppable::class)->create(['price' => 500]);
$cart->addItem(get_class($model), $model->id, 3);

return $cart;
}
}
Loading

0 comments on commit 547a6ce

Please sign in to comment.