Cart::applyCartCleared()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace SyliusCart\Domain\Model;
6
7
use Broadway\EventSourcing\EventSourcedAggregateRoot;
8
use Money\Currency;
9
use Money\Money;
10
use Ramsey\Uuid\UuidInterface;
11
use SyliusCart\Domain\Adapter\AvailableCurrencies\AvailableCurrenciesProviderInterface;
12
use SyliusCart\Domain\Event\CartCleared;
13
use SyliusCart\Domain\Event\CartInitialized;
14
use SyliusCart\Domain\Event\CartItemAdded;
15
use SyliusCart\Domain\Event\CartItemQuantityChanged;
16
use SyliusCart\Domain\Event\CartItemRemoved;
17
use SyliusCart\Domain\Exception\CartCurrencyMismatchException;
18
use SyliusCart\Domain\Exception\CartCurrencyNotSupportedException;
19
use SyliusCart\Domain\Exception\InvalidCartItemUnitPriceException;
20
use SyliusCart\Domain\ModelCollection\CartItemCollection;
21
use SyliusCart\Domain\ModelCollection\CartItems;
22
use SyliusCart\Domain\ValueObject\CartItemQuantity;
23
use SyliusCart\Domain\ValueObject\ProductCode;
24
25
/**
26
 * @author Arkadiusz Krakowiak <[email protected]>
27
 */
28
final class Cart extends EventSourcedAggregateRoot implements CartContract
29
{
30
    /**
31
     * @var UuidInterface
32
     */
33
    private $cartId;
34
35
    /**
36
     * @var CartItemCollection
37
     */
38
    private $cartItems;
39
40
    /**
41
     * @var Currency
42
     */
43
    private $cartCurrency;
44
45
    /**
46
     * @var AvailableCurrenciesProviderInterface
47
     */
48
    private $availableCurrenciesProvider;
49
50
    /**
51
     * @param AvailableCurrenciesProviderInterface $availableCurrenciesProvider
52
     */
53
    private function __construct(AvailableCurrenciesProviderInterface $availableCurrenciesProvider)
54
    {
55
        $this->availableCurrenciesProvider = $availableCurrenciesProvider;
56
    }
57
58
    /**
59
     * @param UuidInterface $cartId
60
     * @param string $currencyCode
61
     * @param AvailableCurrenciesProviderInterface $availableCurrenciesProvider
62
     *
63
     * @return CartContract
64
     */
65
    public static function initialize(
66
        UuidInterface $cartId,
67
        string $currencyCode,
68
        AvailableCurrenciesProviderInterface $availableCurrenciesProvider
69
    ): CartContract {
70
        $cart = new self($availableCurrenciesProvider);
71
72
        $cartCurrency = new Currency($currencyCode);
73
74
        if (!$cartCurrency->isAvailableWithin($cart->availableCurrenciesProvider->provideAvailableCurrencies())) {
75
            throw new CartCurrencyNotSupportedException();
76
        }
77
78
        $cart->apply(CartInitialized::occur($cartId, $cartCurrency));
79
80
        return $cart;
81
    }
82
83
    /**
84
     * @param AvailableCurrenciesProviderInterface $availableCurrenciesProvider
85
     *
86
     * @return CartContract
87
     */
88
    public static function createWithAdapters(
89
        AvailableCurrenciesProviderInterface $availableCurrenciesProvider
90
    ): CartContract {
91
        return new self($availableCurrenciesProvider);
92
    }
93
94
    /**
95
     * @param string $productCode
96
     * @param int $quantity
97
     * @param int $price
98
     * @param string $productCurrencyCode
99
     */
100
    public function addProductToCart(string $productCode, int $quantity, int $price, string $productCurrencyCode): void
101
    {
102
        $price = new Money($price, new Currency($productCurrencyCode));
103
        $quantity = CartItemQuantity::create($quantity);
104
        $productCode = ProductCode::fromString($productCode);
105
106
        if ($price->isNegative()) {
107
            throw new InvalidCartItemUnitPriceException('Cart item unit price cannot be below zero.');
108
        }
109
110
        if (!$this->cartCurrency->equals($price->getCurrency())) {
111
            throw new CartCurrencyMismatchException($this->cartCurrency, $price->getCurrency());
112
        }
113
114
        $cartItem = CartItem::create(
115
            $productCode,
116
            $quantity,
117
            $price
118
        );
119
120
        $this->apply(CartItemAdded::occur($this->cartId, $cartItem));
121
    }
122
123
    /**
124
     * @param string $productCode
125
     */
126
    public function removeProductFromCart(string $productCode): void
127
    {
128
        $cartItem = $this->cartItems->findOneByProductCode(ProductCode::fromString($productCode));
129
130
        $this->apply(CartItemRemoved::occur($this->cartId, $cartItem->productCode()));
131
    }
132
133
    public function clear(): void
134
    {
135
        if (!$this->cartItems->isEmpty()) {
136
            $this->apply(CartCleared::occur($this->cartId));
137
        }
138
    }
139
140
    /**
141
     * @param string $productCode
142
     * @param int $quantity
143
     */
144
    public function changeProductQuantity(string $productCode, int $quantity): void
145
    {
146
        $productCode = ProductCode::fromString($productCode);
147
        $cartItem = $this->cartItems->findOneByProductCode($productCode);
148
        $newQuantity = CartItemQuantity::create($quantity);
149
150
        $this->apply(CartItemQuantityChanged::occur($this->cartId, $productCode, $cartItem->quantity(), $newQuantity));
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function getAggregateRootId(): UuidInterface
157
    {
158
        return $this->cartId;
159
    }
160
161
    /**
162
     * @param CartInitialized $event
163
     */
164
    protected function applyCartInitialized(CartInitialized $event): void
165
    {
166
        $this->cartId = $event->getCartId();
167
        $this->cartCurrency = $event->getCartCurrency();
168
        $this->cartItems = CartItems::createEmpty();
169
    }
170
171
    /**
172
     * @param CartItemAdded $event
173
     */
174
    protected function applyCartItemAdded(CartItemAdded $event): void
175
    {
176
        $this->cartItems->add($event->getCartItem());
177
    }
178
179
    /**
180
     * @param CartItemRemoved $event
181
     */
182
    protected function applyCartItemRemoved(CartItemRemoved $event): void
183
    {
184
        $cartItem = $this->cartItems->findOneByProductCode($event->getProductCode());
185
        $this->cartItems->remove($cartItem);
186
    }
187
188
    /**
189
     * @param CartCleared $event
190
     */
191
    protected function applyCartCleared(CartCleared $event): void
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
192
    {
193
        $this->cartItems->clear();
194
    }
195
}
196