Passed
Push — master ( 03c0bd...d9a7d5 )
by
unknown
05:08
created

Cart::getDiscountVAT()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Thelia\Model;
4
5
use Propel\Runtime\ActiveQuery\Criteria;
6
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
7
use Thelia\Core\Event\Cart\CartDuplicationEvent;
8
use Thelia\Core\Event\Cart\CartItemDuplicationItem;
9
use Thelia\Core\Event\TheliaEvents;
10
use Thelia\Model\Base\Cart as BaseCart;
0 ignored issues
show
Bug introduced by
The type Thelia\Model\Base\Cart was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Thelia\TaxEngine\Calculator;
12
13
class Cart extends BaseCart
14
{
15
    /**
16
     * Duplicate the current existing cart. Only the token is changed
17
     *
18
     * @param string $token
19
     * @param Customer $customer
20
     * @param Currency $currency
21
     * @param EventDispatcherInterface $dispatcher
22
     * @return Cart|bool
23
     * @throws \Exception
24
     * @throws \Propel\Runtime\Exception\PropelException
25
     */
26
    public function duplicate(
27
        $token,
28
        Customer $customer = null,
29
        Currency $currency = null,
30
        EventDispatcherInterface $dispatcher = null
31
    ) {
32
        if (!$dispatcher) {
33
            return false;
34
        }
35
36
        $cartItems = $this->getCartItems();
37
38
        $cart = new Cart();
39
        $cart->setAddressDeliveryId($this->getAddressDeliveryId());
40
        $cart->setAddressInvoiceId($this->getAddressInvoiceId());
41
        $cart->setToken($token);
42
        $discount = 0;
43
44
        if (null === $currency) {
45
            $currencyQuery = CurrencyQuery::create();
46
            $currency = $currencyQuery->findPk($this->getCurrencyId()) ?: $currencyQuery->findOneByByDefault(1);
47
        }
48
49
        $cart->setCurrency($currency);
50
51
        if ($customer) {
52
            $cart->setCustomer($customer);
53
54
            if ($customer->getDiscount() > 0) {
55
                $discount = $customer->getDiscount();
56
            }
57
        }
58
59
        $cart->save();
60
61
        foreach ($cartItems as $cartItem) {
62
            $product = $cartItem->getProduct();
63
            $productSaleElements = $cartItem->getProductSaleElements();
64
65
            if ($product
66
                &&
67
                $productSaleElements
68
                &&
69
                (int)$product->getVisible() === 1
70
                &&
71
                ($productSaleElements->getQuantity() >= $cartItem->getQuantity() || $product->getVirtual() === 1 || !ConfigQuery::checkAvailableStock())
72
            ) {
73
                $item = new CartItem();
74
                $item->setCart($cart);
75
                $item->setProductId($cartItem->getProductId());
76
                $item->setQuantity($cartItem->getQuantity());
77
                $item->setProductSaleElements($productSaleElements);
78
                $prices = $productSaleElements->getPricesByCurrency($currency, $discount);
79
                $item
80
                    ->setPrice($prices->getPrice())
81
                    ->setPromoPrice($prices->getPromoPrice())
82
                    ->setPromo($productSaleElements->getPromo());
83
84
                $item->save();
85
                $dispatcher->dispatch(TheliaEvents::CART_ITEM_DUPLICATE, new CartItemDuplicationItem($item, $cartItem));
86
            }
87
        }
88
89
        // Dispatche the duplication event before delting the cart from the database,
90
        $dispatcher->dispatch(TheliaEvents::CART_DUPLICATED, new CartDuplicationEvent($cart, $this));
91
92
        try {
93
            $this->delete();
94
        } catch (\Exception $e) {
95
            // just fail silently in some cases
96
        }
97
98
        return $cart;
99
    }
100
101
    /**
102
     * Retrieve the last item added in the cart
103
     *
104
     * @return CartItem
105
     */
106
    public function getLastCartItemAdded()
107
    {
108
        return CartItemQuery::create()
109
            ->filterByCartId($this->getId())
110
            ->orderByCreatedAt(Criteria::DESC)
111
            ->findOne()
112
        ;
113
    }
114
115
    /**
116
     *
117
     * Retrieve the total taxed amount.
118
     *
119
     * By default, the total include the discount
120
     *
121
     * /!\ The postage amount is not available so it's the total with or without discount an without postage
122
     *
123
     * @param  Country      $country
124
     * @param bool $withDiscount
125
     * @param  State|null   $state
126
     * @return float
127
     * @throws \Propel\Runtime\Exception\PropelException
128
     */
129
    public function getTaxedAmount(Country $country, $withDiscount = true, State $state = null)
130
    {
131
        $total = 0;
132
133
        foreach ($this->getCartItems() as $cartItem) {
134
            $total += $cartItem->getTotalRealTaxedPrice($country, $state);
135
        }
136
137
        if ($withDiscount) {
138
            $total -= $this->getDiscount();
139
140
            if ($total < 0) {
141
                $total = 0;
142
            }
143
        }
144
145
        return round($total, 2);
146
    }
147
148
    /**
149
     * @param bool $withDiscount
150
     * @param Country|null $country
151
     * @param State|null $state
152
     * @return float
153
     * @throws \Propel\Runtime\Exception\PropelException
154
     * @see getTaxedAmount same as this method but the amount is without taxes
155
     *
156
     */
157
    public function getTotalAmount($withDiscount = true, Country $country = null, State $state = null)
158
    {
159
        $total = 0;
160
161
        foreach ($this->getCartItems() as $cartItem) {
162
            $total += $cartItem->getTotalRealPrice();
163
        }
164
165
        if ($withDiscount) {
166
            $total -= $this->getDiscount(false, $country, $state);
167
168
            if ($total < 0) {
169
                $total = 0;
170
            }
171
        }
172
173
        return round($total, 2);
174
    }
175
176
    /**
177
     * Return the VAT of all items
178
     *
179
     * @param Country $taxCountry
180
     * @param null $taxState
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $taxState is correct as it would always require null to be passed?
Loading history...
181
     * @param bool $withDiscount
182
     * @return float|int|string
183
     * @throws \Propel\Runtime\Exception\PropelException
184
     */
185
    public function getTotalVAT($taxCountry, $taxState = null, $withDiscount = true)
186
    {
187
        return $this->getTaxedAmount($taxCountry, $withDiscount, $taxState) - $this->getTotalAmount($withDiscount, $taxCountry, $taxState);
188
    }
189
190
    /**
191
     * @param $taxCountry
192
     * @param null $taxState
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $taxState is correct as it would always require null to be passed?
Loading history...
193
     * @return float
194
     * @throws \Propel\Runtime\Exception\PropelException
195
     */
196
    public function getDiscountVAT($taxCountry, $taxState = null)
197
    {
198
        return $this->getDiscount(true, $taxCountry, $taxState) - $this->getDiscount(false, $taxCountry, $taxState);
199
    }
200
201
    /**
202
     * Retrieve the total weight for all products in cart
203
     *
204
     * @return float
205
     * @throws \Propel\Runtime\Exception\PropelException
206
     */
207
    public function getWeight()
208
    {
209
        $weight = 0;
210
211
        foreach ($this->getCartItems() as $cartItem) {
212
            $itemWeight = $cartItem->getProductSaleElements()->getWeight();
213
            $itemWeight *= $cartItem->getQuantity();
214
215
            $weight += $itemWeight;
216
        }
217
218
        return $weight;
219
    }
220
221
    /**
222
     * Tell if the cart contains only virtual products
223
     *
224
     * @return bool
225
     * @throws \Propel\Runtime\Exception\PropelException
226
     */
227
    public function isVirtual()
228
    {
229
        foreach ($this->getCartItems() as $cartItem) {
230
            if (0 < $cartItem->getProductSaleElements()->getWeight()) {
231
                return false;
232
            }
233
234
            $product = $cartItem->getProductSaleElements()->getProduct();
235
236
            if (! $product->getVirtual()) {
237
                return false;
238
            }
239
        }
240
241
        // An empty cart is not virtual.
242
        return $this->getCartItems()->count() > 0;
243
    }
244
245
    /**
246
     * @param string $discount
247
     * @return BaseCart|Cart
248
     */
249
    public function setDiscount($discount)
250
    {
251
        return parent::setDiscount(round($discount, 2));
0 ignored issues
show
Bug introduced by
$discount of type string is incompatible with the type double expected by parameter $val of round(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

251
        return parent::setDiscount(round(/** @scrutinizer ignore-type */ $discount, 2));
Loading history...
252
    }
253
254
    /**
255
     * @param bool $withTaxes
256
     * @param \Thelia\Model\Country|null $country
257
     * @param \Thelia\Model\State|null $state
258
     *
259
     * @return float|int|string
260
     * @throws \Propel\Runtime\Exception\PropelException
261
     */
262
    public function getDiscount($withTaxes = true, Country $country = null, State $state = null)
263
    {
264
        if ($withTaxes || null === $country) {
265
            return parent::getDiscount();
266
        }
267
268
        return round(Calculator::getUntaxedCartDiscount($this, $country, $state), 2);
269
    }
270
}
271