Completed
Push — master ( 0f74a6...eca3e7 )
by Kamil
20:39
created

Order::addPayment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 10
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Component\Core\Model;
13
14
use Doctrine\Common\Collections\ArrayCollection;
15
use Doctrine\Common\Collections\Collection;
16
use Sylius\Component\Cart\Model\Cart;
17
use Sylius\Component\Channel\Model\ChannelInterface as BaseChannelInterface;
18
use Sylius\Component\Core\OrderCheckoutStates;
19
use Sylius\Component\Inventory\Model\InventoryUnitInterface;
20
use Sylius\Component\Payment\Model\PaymentInterface as BasePaymentInterface;
21
use Sylius\Component\Promotion\Model\CouponInterface as BaseCouponInterface;
22
use Sylius\Component\Promotion\Model\PromotionInterface as BasePromotionInterface;
23
use Sylius\Component\User\Model\CustomerInterface as BaseCustomerInterface;
24
25
/**
26
 * @author Paweł Jędrzejewski <[email protected]>
27
 * @author Michał Marcinkowski <[email protected]>
28
 */
29
class Order extends Cart implements OrderInterface
30
{
31
    /**
32
     * @var BaseCustomerInterface
33
     */
34
    protected $customer;
35
36
    /**
37
     * @var ChannelInterface
38
     */
39
    protected $channel;
40
41
    /**
42
     * @var AddressInterface
43
     */
44
    protected $shippingAddress;
45
46
    /**
47
     * @var AddressInterface
48
     */
49
    protected $billingAddress;
50
51
    /**
52
     * @var Collection|BasePaymentInterface[]
53
     */
54
    protected $payments;
55
56
    /**
57
     * @var Collection|ShipmentInterface[]
58
     */
59
    protected $shipments;
60
61
    /**
62
     * @var string
63
     */
64
    protected $currency;
65
66
    /**
67
     * @var float
68
     */
69
    protected $exchangeRate = 1.0;
70
71
    /**
72
     * @var BaseCouponInterface
73
     */
74
    protected $promotionCoupon;
75
76
    /**
77
     * @var string
78
     */
79
    protected $checkoutState = OrderCheckoutStates::STATE_CART;
80
81
    /**
82
     * @var string
83
     */
84
    protected $paymentState = BasePaymentInterface::STATE_NEW;
85
86
    /**
87
     * It depends on the status of all order shipments.
88
     *
89
     * @var string
90
     */
91
    protected $shippingState = OrderShippingStates::CHECKOUT;
92
93
    /**
94
     * @var Collection|BasePromotionInterface[]
95
     */
96
    protected $promotions;
97
98
    public function __construct()
99
    {
100
        parent::__construct();
101
102
        $this->payments = new ArrayCollection();
103
        $this->shipments = new ArrayCollection();
104
        $this->promotions = new ArrayCollection();
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function getCustomer()
111
    {
112
        return $this->customer;
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function setCustomer(BaseCustomerInterface $customer = null)
119
    {
120
        $this->customer = $customer;
121
122
        return $this;
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function getChannel()
129
    {
130
        return $this->channel;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function setChannel(BaseChannelInterface $channel = null)
137
    {
138
        $this->channel = $channel;
0 ignored issues
show
Documentation Bug introduced by
It seems like $channel can also be of type object<Sylius\Component\...Model\ChannelInterface>. However, the property $channel is declared as type object<Sylius\Component\...Model\ChannelInterface>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function getUser()
145
    {
146
        if (null === $this->customer) {
147
            return null;
148
        }
149
150
        return $this->customer->getUser();
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function getShippingAddress()
157
    {
158
        return $this->shippingAddress;
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function setShippingAddress(AddressInterface $address)
165
    {
166
        $this->shippingAddress = $address;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function getBillingAddress()
173
    {
174
        return $this->billingAddress;
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function setBillingAddress(AddressInterface $address)
181
    {
182
        $this->billingAddress = $address;
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function getCheckoutState()
189
    {
190
        return $this->checkoutState;
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function setCheckoutState($checkoutState)
197
    {
198
        $this->checkoutState = $checkoutState;
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function getPaymentState()
205
    {
206
        return $this->paymentState;
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function setPaymentState($paymentState)
213
    {
214
        $this->paymentState = $paymentState;
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function getItemUnits()
221
    {
222
        $units = new ArrayCollection();
223
224
        /** @var $item OrderItem */
225
        foreach ($this->getItems() as $item) {
226
            foreach ($item->getUnits() as $unit) {
227
                $units->add($unit);
228
            }
229
        }
230
231
        return $units;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237
    public function getItemUnitsByVariant(ProductVariantInterface $variant)
238
    {
239
        return $this->getItemUnits()->filter(function (OrderItemUnitInterface $itemUnit) use ($variant) {
240
            return $variant === $itemUnit->getStockable();
241
        });
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247
    public function getPayments()
248
    {
249
        return $this->payments;
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255
    public function hasPayments()
256
    {
257
        return !$this->payments->isEmpty();
258
    }
259
260
    /**
261
     * {@inheritdoc}
262
     */
263
    public function addPayment(BasePaymentInterface $payment)
264
    {
265
        /** @var $payment PaymentInterface */
266
        if (!$this->hasPayment($payment)) {
267
            $this->payments->add($payment);
268
            $payment->setOrder($this);
269
270
            $this->setPaymentState($payment->getState());
271
        }
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     */
277
    public function removePayment(BasePaymentInterface $payment)
278
    {
279
        /** @var $payment PaymentInterface */
280
        if ($this->hasPayment($payment)) {
281
            $this->payments->removeElement($payment);
282
            $payment->setOrder(null);
283
        }
284
    }
285
286
    /**
287
     * {@inheritdoc}
288
     */
289
    public function hasPayment(BasePaymentInterface $payment)
290
    {
291
        return $this->payments->contains($payment);
292
    }
293
294
    /**
295
     * {@inheritdoc}
296
     */
297
    public function getLastPayment($state = BasePaymentInterface::STATE_NEW)
298
    {
299
        if ($this->payments->isEmpty()) {
300
            return null;
301
        }
302
303
        $payment = $this->payments->filter(function (BasePaymentInterface $payment) use ($state) {
304
            return $payment->getState() === $state;
305
        })->last();
306
307
        return $payment !== false ? $payment : null;
308
    }
309
310
    /**
311
     * {@inheritdoc}
312
     */
313
    public function getShipments()
314
    {
315
        return $this->shipments;
316
    }
317
318
    /**
319
     * {@inheritdoc}
320
     */
321
    public function hasShipments()
322
    {
323
        return !$this->shipments->isEmpty();
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function addShipment(ShipmentInterface $shipment)
330
    {
331
        if (!$this->hasShipment($shipment)) {
332
            $shipment->setOrder($this);
333
            $this->shipments->add($shipment);
334
        }
335
    }
336
337
    /**
338
     * {@inheritdoc}
339
     */
340
    public function removeShipment(ShipmentInterface $shipment)
341
    {
342
        if ($this->hasShipment($shipment)) {
343
            $shipment->setOrder(null);
344
            $this->shipments->removeElement($shipment);
345
        }
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351
    public function hasShipment(ShipmentInterface $shipment)
352
    {
353
        return $this->shipments->contains($shipment);
354
    }
355
356
    /**
357
     * @return null|BaseCouponInterface
358
     */
359
    public function getPromotionCoupon()
360
    {
361
        return $this->promotionCoupon;
362
    }
363
364
    /**
365
     * {@inheritdoc}
366
     */
367
    public function setPromotionCoupon(BaseCouponInterface $coupon = null)
368
    {
369
        $this->promotionCoupon = $coupon;
370
    }
371
372
    /**
373
     * {@inheritdoc}
374
     */
375
    public function getPromotionSubjectTotal()
376
    {
377
        return $this->getItemsTotal();
378
    }
379
380
    /**
381
     * {@inheritdoc}
382
     */
383
    public function getPromotionSubjectCount()
384
    {
385
        return $this->getTotalQuantity();
386
    }
387
388
    /**
389
     * {@inheritdoc}
390
     */
391
    public function getCurrency()
392
    {
393
        return $this->currency;
394
    }
395
396
    /**
397
     * {@inheritdoc}
398
     */
399
    public function setCurrency($currency)
400
    {
401
        $this->currency = $currency;
402
403
        return $this;
404
    }
405
406
    /**
407
     * {@inheritdoc}
408
     */
409
    public function getExchangeRate()
410
    {
411
        return $this->exchangeRate;
412
    }
413
414
    /**
415
     * {@inheritdoc}
416
     */
417
    public function setExchangeRate($exchangeRate)
418
    {
419
        $this->exchangeRate = (float) $exchangeRate;
420
421
        return $this;
422
    }
423
424
    /**
425
     * {@inheritdoc}
426
     */
427
    public function getShippingState()
428
    {
429
        return $this->shippingState;
430
    }
431
432
    /**
433
     * {@inheritdoc}
434
     */
435
    public function setShippingState($state)
436
    {
437
        $this->shippingState = $state;
438
439
        return $this;
440
    }
441
442
    /**
443
     * {@inheritdoc}
444
     */
445
    public function isBackorder()
446
    {
447
        foreach ($this->getItemUnits() as $itemUnit) {
448
            if (InventoryUnitInterface::STATE_BACKORDERED === $itemUnit->getInventoryState()) {
449
                return true;
450
            }
451
        }
452
453
        return false;
454
    }
455
456
    /**
457
     * Gets the last updated shipment of the order
458
     *
459
     * @return false|ShipmentInterface
460
     */
461
    public function getLastShipment()
462
    {
463
        if ($this->shipments->isEmpty()) {
464
            return false;
465
        }
466
467
        $last = $this->shipments->first();
468
        foreach ($this->shipments as $shipment) {
469
            if ($shipment->getUpdatedAt() > $last->getUpdatedAt()) {
470
                $last = $shipment;
471
            }
472
        }
473
474
        return $last;
475
    }
476
477
    /**
478
     * {@inheritdoc}
479
     */
480
    public function isInvoiceAvailable()
481
    {
482
        if (false !== $lastShipment = $this->getLastShipment()) {
483
            return in_array($lastShipment->getState(), [ShipmentInterface::STATE_RETURNED, ShipmentInterface::STATE_SHIPPED]);
484
        }
485
486
        return false;
487
    }
488
489
    /**
490
     * {@inheritdoc}
491
     */
492
    public function hasPromotion(BasePromotionInterface $promotion)
493
    {
494
        return $this->promotions->contains($promotion);
495
    }
496
497
    /**
498
     * {@inheritdoc}
499
     */
500
    public function addPromotion(BasePromotionInterface $promotion)
501
    {
502
        if (!$this->hasPromotion($promotion)) {
503
            $this->promotions->add($promotion);
504
        }
505
506
        return $this;
507
    }
508
509
    /**
510
     * {@inheritdoc}
511
     */
512
    public function removePromotion(BasePromotionInterface $promotion)
513
    {
514
        if ($this->hasPromotion($promotion)) {
515
            $this->promotions->removeElement($promotion);
516
        }
517
518
        return $this;
519
    }
520
521
    /**
522
     * {@inheritdoc}
523
     */
524
    public function getPromotions()
525
    {
526
        return $this->promotions;
527
    }
528
529
    /**
530
     * @return int
531
     */
532
    public function getPromotionsTotalRecursively()
533
    {
534
        return
535
            $this->getAdjustmentsTotalRecursively(AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT) +
536
            $this->getAdjustmentsTotalRecursively(AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT)
537
        ;
538
    }
539
}
540