Order   F
last analyzed

Complexity

Total Complexity 80

Size/Duplication

Total Lines 441
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 147
dl 0
loc 441
ccs 0
cts 187
cp 0
rs 2
c 1
b 0
f 1
wmc 80

56 Methods

Rating   Name   Duplication   Size   Complexity  
A removePromotion() 0 3 1
A getShippingTax() 0 10 3
A getPayments() 0 3 1
A addShipment() 0 4 1
A addPayment() 0 4 1
A setPromotionCoupon() 0 3 1
A getShipments() 0 3 1
A getEmail() 0 3 1
A getPaymentState() 0 3 1
A setPaymentState() 0 3 1
A hasPromotion() 0 3 1
A addVoucher() 0 3 1
A getPromotionSubjectTotal() 0 3 1
A removeVoucher() 0 3 1
A getPromotionCoupon() 0 3 1
A removePayment() 0 4 1
A getShippingPrice() 0 16 3
A getShippingTotal() 0 3 1
A getVouchers() 0 3 1
A getShippingState() 0 3 1
A hasShipments() 0 3 1
A addPromotion() 0 3 1
A getPromotionSubjectCount() 0 3 1
A setShippingState() 0 3 1
A removeShipment() 0 4 1
A getPromotions() 0 3 1
A __construct() 0 7 1
A setUser() 0 3 1
A getUser() 0 3 1
A removeShipments() 0 5 2
A setEmail() 0 3 1
A getLastPayment() 0 11 4
A setCheckoutState() 0 3 1
A getItemsNetTotal() 0 3 1
A setTrackingMail() 0 3 1
A getItemsTaxTotal() 0 10 3
A setCurrencyCode() 0 3 1
A isFreeShipping() 0 3 1
A getUnitTotal() 0 7 2
A getUnitTaxTotal() 0 7 2
A getDiscountedUnitPriceTotal() 0 7 2
A isShippable() 0 3 1
A getCheckoutState() 0 3 1
A getUnitPriceTotal() 0 7 2
A getItemUnits() 0 13 3
A isPayed() 0 3 1
A getCustomerEmail() 0 6 2
A getDiscountedTotal() 0 24 5
A getVoucherAmountTotal() 0 10 2
A setShippable() 0 3 1
A isTrackingMail() 0 3 1
A getTaxTotal() 0 16 3
A getAddress() 0 3 1
A getCurrencyCode() 0 3 1
A getToken() 0 3 1
A setToken() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Order often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Order, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Order.php
4
 *
5
 * @since 14/08/16
6
 * @author gseidel
7
 */
8
9
namespace Enhavo\Bundle\ShopBundle\Entity;
10
11
use Doctrine\Common\Collections\ArrayCollection;
12
use Doctrine\Common\Collections\Collection;
13
use Enhavo\Bundle\ShopBundle\Model\AddressSubjectInterface;
14
use Enhavo\Bundle\ShopBundle\Model\OrderItemInterface;
15
use Enhavo\Bundle\ShopBundle\State\OrderCheckoutStates;
16
use Enhavo\Bundle\ShopBundle\State\OrderPaymentStates;
17
use Enhavo\Bundle\ShopBundle\State\OrderShippingStates;
18
use Enhavo\Bundle\UserBundle\Model\UserInterface;
19
use Enhavo\Bundle\ShopBundle\Model\OrderInterface;
20
use Enhavo\Bundle\ShopBundle\Model\ShipmentInterface;
21
use Enhavo\Bundle\ShopBundle\Model\AdjustmentInterface;
22
use Sylius\Component\Payment\Model\PaymentInterface;
23
use Sylius\Component\Promotion\Model\PromotionCouponAwarePromotionSubjectInterface;
24
use Sylius\Component\Promotion\Model\PromotionInterface;
25
use Sylius\Component\Order\Model\Order as SyliusOrder;
26
use Sylius\Component\Promotion\Model\PromotionCouponInterface;
27
28
class Order extends SyliusOrder implements OrderInterface
29
{
30
    use AddressSubjectTrait;
31
32
    private string $paymentState = OrderPaymentStates::STATE_CART;
33
    private string $shippingState = OrderShippingStates::STATE_CART;
34
    private string $checkoutState = OrderCheckoutStates::STATE_CART;
35
36
    private ?PromotionCouponInterface $promotionCoupon= null;
37
    private ?UserInterface $user = null;
38
39
    private ?string $email = null;
40
    private ?string $token = null;
41
    private ?bool $trackingMail = false;
42
    private ?bool $shippable = true;
43
    private ?string $currencyCode = null;
44
45
    /** @var Collection|PaymentInterface[] */
46
    private $payments;
47
48
    /** @var Collection|ShipmentInterface[] */
49
    private $shipments;
50
51
    /** @var Collection */
52
    private $promotions;
53
54
    /** @var Collection */
55
    private $vouchers;
56
57
    public function __construct()
58
    {
59
        parent::__construct();
60
        $this->promotions = new ArrayCollection();
61
        $this->payments = new ArrayCollection();
62
        $this->shipments = new ArrayCollection();
63
        $this->vouchers = new ArrayCollection();
64
    }
65
66
    public function setPaymentState(?string $paymentState): void
67
    {
68
        $this->paymentState = $paymentState;
69
    }
70
71
    public function getPaymentState(): ?string
72
    {
73
        return $this->paymentState;
74
    }
75
76
    public function setShippingState(?string $shippingState): void
77
    {
78
        $this->shippingState = $shippingState;
79
    }
80
81
    public function getShippingState(): ?string
82
    {
83
        return $this->shippingState;
84
    }
85
86
    public function setPromotionCoupon(?PromotionCouponInterface $promotionCoupon)
87
    {
88
        $this->promotionCoupon = $promotionCoupon;
89
    }
90
91
    public function getPromotionCoupon(): ?PromotionCouponInterface
92
    {
93
        return $this->promotionCoupon;
94
    }
95
96
    public function addPromotion(PromotionInterface $promotions): void
97
    {
98
        $this->promotions[] = $promotions;
99
    }
100
101
    public function removePromotion(PromotionInterface $promotions): void
102
    {
103
        $this->promotions->removeElement($promotions);
104
    }
105
106
    public function getPromotions(): Collection
107
    {
108
        return $this->promotions;
109
    }
110
111
    public function getVouchers(): Collection
112
    {
113
        return $this->vouchers;
114
    }
115
116
    public function addVoucher($voucher)
117
    {
118
        $this->vouchers->add($voucher);
119
    }
120
121
    public function removeVoucher($voucher)
122
    {
123
        $this->vouchers->removeElement($voucher);
124
    }
125
126
    public function getPromotionSubjectTotal(): int
127
    {
128
        return $this->getItemsTotal();
129
    }
130
131
    public function hasPromotion(PromotionInterface $promotion): bool
132
    {
133
       return $this->promotions->contains($promotion);
134
    }
135
136
    public function getPromotionSubjectCount(): int
137
    {
138
        return $this->getTotalQuantity();
139
    }
140
141
    public function addPayment(PaymentInterface $payment)
142
    {
143
        $this->payments->add($payment);
144
        $payment->setOrder($this);
0 ignored issues
show
Bug introduced by
The method setOrder() does not exist on Sylius\Component\Payment\Model\PaymentInterface. It seems like you code against a sub-type of Sylius\Component\Payment\Model\PaymentInterface such as Enhavo\Bundle\ShopBundle\Entity\Payment or Enhavo\Bundle\ShopBundle\Entity\Payment. ( Ignorable by Annotation )

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

144
        $payment->/** @scrutinizer ignore-call */ 
145
                  setOrder($this);
Loading history...
145
    }
146
147
    public function removePayment(PaymentInterface $payment)
148
    {
149
        $this->payments->removeElement($payment);
150
        $payment->setOrder(null);
151
    }
152
153
    /**
154
     * @return Collection|array<PaymentInterface>
155
     */
156
    public function getPayments(): Collection|array
157
    {
158
        return $this->payments;
159
    }
160
161
    public function addShipment(ShipmentInterface $shipment)
162
    {
163
        $this->shipments->add($shipment);
164
        $shipment->setOrder($this);
165
    }
166
167
    public function hasShipments(): bool
168
    {
169
        return $this->shipments->count() > 0;
170
    }
171
172
    public function removeShipment(ShipmentInterface $shipment)
173
    {
174
        $this->shipments->removeElement($shipment);
175
        $shipment->setOrder(null);
176
    }
177
178
    /**
179
     * @return Collection|array<ShipmentInterface>
180
     */
181
    public function getShipments(): Collection|array
182
    {
183
        return $this->shipments;
184
    }
185
186
    public function removeShipments()
187
    {
188
        $shipments = $this->getShipments();
189
        foreach ($shipments as $shipment) {
190
            $this->removeShipment($shipment);
191
        }
192
    }
193
194
    public function setEmail(?string $email)
195
    {
196
        $this->email = $email;
197
    }
198
199
    public function getEmail(): ?string
200
    {
201
        return $this->email;
202
    }
203
204
    public function setUser(UserInterface $user = null)
205
    {
206
        $this->user = $user;
207
    }
208
209
    public function getUser()
210
    {
211
        return $this->user;
212
    }
213
214
    public function getShippingTotal()
215
    {
216
        return $this->getShippingPrice() + $this->getShippingTax();
217
    }
218
219
    public function getShippingPrice()
220
    {
221
        $total = 0;
222
        $shippingAdjustments = $this->getAdjustments(AdjustmentInterface::SHIPPING_ADJUSTMENT);
223
        $shippingPromotionAdjustments = $this->getAdjustments(AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT);
224
225
226
        foreach($shippingAdjustments as $adjustment) {
227
            $total += $adjustment->getAmount();
228
        }
229
230
        foreach($shippingPromotionAdjustments as $adjustment) {
231
            $total += $adjustment->getAmount();
232
        }
233
234
        return $total;
235
    }
236
237
    public function getShippingTax()
238
    {
239
        $total = 0;
240
        $tax = $this->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
241
        foreach($tax as $adjustment) {
242
            if($adjustment->getOriginType() === ShipmentInterface::class) {
243
                $total += $adjustment->getAmount();
244
            }
245
        }
246
        return $total;
247
    }
248
249
    public function getDiscountedTotal()
250
    {
251
        $total = 0;
252
        $adjustments = $this->getAdjustmentsRecursively(AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT);
253
        foreach($adjustments as $adjustment) {
254
            $total += $adjustment->getAmount();
255
        }
256
257
        $adjustments = $this->getAdjustmentsRecursively(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT);
258
        foreach($adjustments as $adjustment) {
259
            $total += $adjustment->getAmount();
260
        }
261
262
        $adjustments = $this->getAdjustmentsRecursively(AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT);
263
        foreach($adjustments as $adjustment) {
264
            $total += $adjustment->getAmount();
265
        }
266
267
        $adjustments = $this->getAdjustmentsRecursively(AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT);
268
        foreach($adjustments as $adjustment) {
269
            $total += $adjustment->getAmount();
270
        }
271
272
        return $total;
273
    }
274
275
    public function getUnitTotal()
276
    {
277
        $total = 0;
278
        foreach($this->getItems() as $items) {
279
            $total += $items->getTotal();
280
        }
281
        return $total;
282
    }
283
284
    public function getUnitPriceTotal()
285
    {
286
        $total = 0;
287
        foreach($this->getItems() as $items) {
288
            $total += $items->getUnitPriceTotal();
289
        }
290
        return $total;
291
    }
292
293
    public function getDiscountedUnitPriceTotal()
294
    {
295
        $total = 0;
296
        foreach($this->getItems() as $items) {
297
            $total += $items->getDiscountedUnitPriceTotal();
298
        }
299
        return $total;
300
    }
301
302
    public function getUnitTaxTotal()
303
    {
304
        $total = 0;
305
        foreach($this->getItems() as $items) {
306
            $total += $items->getTaxTotal();
307
        }
308
        return $total;
309
    }
310
311
    public function getTaxTotal()
312
    {
313
        $total = 0;
314
        $total += $this->getUnitTaxTotal();
315
316
        $taxes = $this->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
317
        foreach($taxes as $adjustment) {
318
            $total += $adjustment->getAmount();
319
        }
320
321
        $taxes = $this->getAdjustments(AdjustmentInterface::TAX_SHIPPING_ADJUSTMENT);
322
        foreach($taxes as $adjustment) {
323
            $total += $adjustment->getAmount();
324
        }
325
326
        return $total;
327
    }
328
329
    public function getCustomerEmail()
330
    {
331
        if($this->getUser() !== null) {
332
            return $this->getUser()->getEmail();
333
        }
334
        return $this->getEmail();
335
    }
336
337
    /**
338
     * @return string
339
     */
340
    public function getToken()
341
    {
342
        return $this->token;
343
    }
344
345
    /**
346
     * @param string $token
347
     */
348
    public function setToken($token)
349
    {
350
        $this->token = $token;
351
    }
352
353
    /**
354
     * @return boolean
355
     */
356
    public function isTrackingMail()
357
    {
358
        return $this->trackingMail;
359
    }
360
361
    /**
362
     * @param boolean $trackingMail
363
     */
364
    public function setTrackingMail($trackingMail)
365
    {
366
        $this->trackingMail = $trackingMail;
367
    }
368
369
    public function isFreeShipping()
370
    {
371
        return $this->getShippingTotal() === 0;
372
    }
373
374
    public function isPayed()
375
    {
376
        return $this->paymentState === PaymentInterface::STATE_COMPLETED;
377
    }
378
379
    public function getCheckoutState(): string
380
    {
381
        return $this->checkoutState;
382
    }
383
384
    public function setCheckoutState(string $checkoutState): void
385
    {
386
        $this->checkoutState = $checkoutState;
387
    }
388
389
    public function isShippable()
390
    {
391
        return $this->shippable;
392
    }
393
394
    public function setShippable($value)
395
    {
396
        $this->shippable = $value;
397
    }
398
399
    public function getAddress(): AddressSubjectInterface
400
    {
401
        return $this;
402
    }
403
404
    public function getItemUnits(): Collection
405
    {
406
        /** @var ArrayCollection<int, OrderItemInterface> $units */
407
        $units = new ArrayCollection();
408
409
        /** @var OrderItem $item */
410
        foreach ($this->getItems() as $item) {
411
            foreach ($item->getUnits() as $unit) {
412
                $units->add($unit);
413
            }
414
        }
415
416
        return $units;
417
    }
418
419
    public function getLastPayment(?string $state = null): ?PaymentInterface
420
    {
421
        if ($this->payments->isEmpty()) {
422
            return null;
423
        }
424
425
        $payment = $this->payments->filter(function (PaymentInterface $payment) use ($state): bool {
426
            return null === $state || $payment->getState() === $state;
427
        })->last();
428
429
        return $payment !== false ? $payment : null;
430
    }
431
432
    public function getCurrencyCode(): ?string
433
    {
434
        return $this->currencyCode;
435
    }
436
437
    public function setCurrencyCode(?string $currencyCode): void
438
    {
439
        $this->currencyCode = $currencyCode;
440
    }
441
442
    public function getItemsTaxTotal()
443
    {
444
        $tax = 0;
445
        foreach ($this->items as $item) {
446
            $adjustments = $item->getAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
447
            foreach ($adjustments as $adjustment) {
448
                $tax += $adjustment->getAmount();
449
            }
450
        }
451
        return $tax;
452
    }
453
454
    public function getVoucherAmountTotal()
455
    {
456
        $amount = 0;
457
458
        $adjustments = $this->getAdjustmentsRecursively(AdjustmentInterface::VOUCHER_ADJUSTMENT);
459
        foreach ($adjustments as $adjustment) {
460
            $amount += $adjustment->getAmount();
461
        }
462
463
        return $amount;
464
    }
465
466
    public function getItemsNetTotal()
467
    {
468
        return $this->getItemsTotal() - $this->getItemsTaxTotal();
469
    }
470
}
471