Completed
Push — master ( d81c19...f57266 )
by Kamil
20s
created

src/Sylius/Component/Order/Model/OrderItem.php (1 issue)

assigning incompatible types to properties.

Bug Documentation Major

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
declare(strict_types=1);
13
14
namespace Sylius\Component\Order\Model;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Doctrine\Common\Collections\Collection;
18
19
class OrderItem implements OrderItemInterface
20
{
21
    /**
22
     * @var mixed
23
     */
24
    protected $id;
25
26
    /**
27
     * @var OrderInterface|null
28
     */
29
    protected $order;
30
31
    /**
32
     * @var int
33
     */
34
    protected $quantity = 0;
35
36
    /**
37
     * @var int
38
     */
39
    protected $unitPrice = 0;
40
41
    /**
42
     * @var int
43
     */
44
    protected $total = 0;
45
46
    /**
47
     * @var bool
48
     */
49
    protected $immutable = false;
50
51
    /**
52
     * @var Collection|OrderItemUnitInterface[]
53
     */
54
    protected $units;
55
56
    /**
57
     * @var int
58
     */
59
    protected $unitsTotal = 0;
60
61
    /**
62
     * @var Collection|AdjustmentInterface[]
63
     */
64
    protected $adjustments;
65
66
    /**
67
     * @var int
68
     */
69
    protected $adjustmentsTotal = 0;
70
71
    public function __construct()
72
    {
73
        $this->adjustments = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Doctrine\Common\Collections\ArrayCollection() of type object<Doctrine\Common\C...ctions\ArrayCollection> is incompatible with the declared type object<Doctrine\Common\C...l\AdjustmentInterface>> of property $adjustments.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
74
        $this->units = new ArrayCollection();
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function getId()
81
    {
82
        return $this->id;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function getQuantity(): int
89
    {
90
        return $this->quantity;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function getOrder(): ?OrderInterface
97
    {
98
        return $this->order;
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function setOrder(?OrderInterface $order): void
105
    {
106
        $currentOrder = $this->getOrder();
107
        if ($currentOrder === $order) {
108
            return;
109
        }
110
111
        $this->order = null;
112
113
        if (null !== $currentOrder) {
114
            $currentOrder->removeItem($this);
115
        }
116
117
        if (null === $order) {
118
            return;
119
        }
120
121
        $this->order = $order;
122
123
        if (!$order->hasItem($this)) {
124
            $order->addItem($this);
125
        }
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function getUnitPrice(): int
132
    {
133
        return $this->unitPrice;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    public function setUnitPrice(int $unitPrice): void
140
    {
141
        $this->unitPrice = $unitPrice;
142
        $this->recalculateUnitsTotal();
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function getTotal(): int
149
    {
150
        return $this->total;
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function recalculateAdjustmentsTotal(): void
157
    {
158
        $this->adjustmentsTotal = 0;
159
160
        foreach ($this->adjustments as $adjustment) {
161
            if (!$adjustment->isNeutral()) {
162
                $this->adjustmentsTotal += $adjustment->getAmount();
163
            }
164
        }
165
166
        $this->recalculateTotal();
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function recalculateUnitsTotal(): void
173
    {
174
        $this->unitsTotal = 0;
175
176
        foreach ($this->units as $unit) {
177
            $this->unitsTotal += $unit->getTotal();
178
        }
179
180
        $this->recalculateTotal();
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186
    public function equals(OrderItemInterface $orderItem): bool
187
    {
188
        return $this === $orderItem;
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194
    public function isImmutable(): bool
195
    {
196
        return $this->immutable;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function setImmutable(bool $immutable): void
203
    {
204
        $this->immutable = $immutable;
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210
    public function getUnits(): Collection
211
    {
212
        return $this->units;
213
    }
214
215
    /**
216
     * {@inheritdoc}
217
     */
218
    public function addUnit(OrderItemUnitInterface $unit): void
219
    {
220
        if ($this !== $unit->getOrderItem()) {
221
            throw new \LogicException('This order item unit is assigned to a different order item.');
222
        }
223
224
        if (!$this->hasUnit($unit)) {
225
            $this->units->add($unit);
226
227
            ++$this->quantity;
228
            $this->unitsTotal += $unit->getTotal();
229
            $this->recalculateTotal();
230
        }
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236
    public function removeUnit(OrderItemUnitInterface $unit): void
237
    {
238
        if ($this->hasUnit($unit)) {
239
            $this->units->removeElement($unit);
240
241
            --$this->quantity;
242
            $this->unitsTotal -= $unit->getTotal();
243
            $this->recalculateTotal();
244
        }
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250
    public function hasUnit(OrderItemUnitInterface $unit): bool
251
    {
252
        return $this->units->contains($unit);
253
    }
254
255
    /**
256
     * {@inheritdoc}
257
     */
258
    public function getAdjustments(?string $type = null): Collection
259
    {
260
        if (null === $type) {
261
            return $this->adjustments;
262
        }
263
264
        return $this->adjustments->filter(function (AdjustmentInterface $adjustment) use ($type) {
265
            return $type === $adjustment->getType();
266
        });
267
    }
268
269
    /**
270
     * {@inheritdoc}
271
     */
272
    public function getAdjustmentsRecursively(?string $type = null): Collection
273
    {
274
        $adjustments = clone $this->getAdjustments($type);
275
276
        foreach ($this->units as $unit) {
277
            foreach ($unit->getAdjustments($type) as $adjustment) {
278
                $adjustments->add($adjustment);
279
            }
280
        }
281
282
        return $adjustments;
283
    }
284
285
    /**
286
     * {@inheritdoc}
287
     */
288
    public function addAdjustment(AdjustmentInterface $adjustment): void
289
    {
290
        if (!$this->hasAdjustment($adjustment)) {
291
            $this->adjustments->add($adjustment);
292
            $this->addToAdjustmentsTotal($adjustment);
293
            $adjustment->setAdjustable($this);
294
        }
295
    }
296
297
    /**
298
     * {@inheritdoc}
299
     */
300
    public function removeAdjustment(AdjustmentInterface $adjustment): void
301
    {
302
        if (!$adjustment->isLocked() && $this->hasAdjustment($adjustment)) {
303
            $this->adjustments->removeElement($adjustment);
304
            $this->subtractFromAdjustmentsTotal($adjustment);
305
            $adjustment->setAdjustable(null);
306
        }
307
    }
308
309
    /**
310
     * {@inheritdoc}
311
     */
312
    public function hasAdjustment(AdjustmentInterface $adjustment): bool
313
    {
314
        return $this->adjustments->contains($adjustment);
315
    }
316
317
    /**
318
     * {@inheritdoc}
319
     */
320
    public function getAdjustmentsTotal(?string $type = null): int
321
    {
322
        if (null === $type) {
323
            return $this->adjustmentsTotal;
324
        }
325
326
        $total = 0;
327
        foreach ($this->getAdjustments($type) as $adjustment) {
328
            if (!$adjustment->isNeutral()) {
329
                $total += $adjustment->getAmount();
330
            }
331
        }
332
333
        return $total;
334
    }
335
336
    /**
337
     * {@inheritdoc}
338
     */
339
    public function getAdjustmentsTotalRecursively(?string $type = null): int
340
    {
341
        $total = 0;
342
343
        foreach ($this->getAdjustmentsRecursively($type) as $adjustment) {
344
            if (!$adjustment->isNeutral()) {
345
                $total += $adjustment->getAmount();
346
            }
347
        }
348
349
        return $total;
350
    }
351
352
    /**
353
     * {@inheritdoc}
354
     */
355
    public function removeAdjustments(?string $type = null): void
356
    {
357
        foreach ($this->getAdjustments($type) as $adjustment) {
358
            $this->removeAdjustment($adjustment);
359
        }
360
    }
361
362
    /**
363
     * {@inheritdoc}
364
     */
365
    public function removeAdjustmentsRecursively(?string $type = null): void
366
    {
367
        $this->removeAdjustments($type);
368
        foreach ($this->units as $unit) {
369
            $unit->removeAdjustments($type);
370
        }
371
    }
372
373
    /**
374
     * Recalculates total after units total or adjustments total change.
375
     */
376
    protected function recalculateTotal(): void
377
    {
378
        $this->total = $this->unitsTotal + $this->adjustmentsTotal;
379
380
        if ($this->total < 0) {
381
            $this->total = 0;
382
        }
383
384
        if (null !== $this->order) {
385
            $this->order->recalculateItemsTotal();
386
        }
387
    }
388
389
    /**
390
     * @param AdjustmentInterface $adjustment
391
     */
392
    protected function addToAdjustmentsTotal(AdjustmentInterface $adjustment): void
393
    {
394
        if (!$adjustment->isNeutral()) {
395
            $this->adjustmentsTotal += $adjustment->getAmount();
396
            $this->recalculateTotal();
397
        }
398
    }
399
400
    /**
401
     * @param AdjustmentInterface $adjustment
402
     */
403
    protected function subtractFromAdjustmentsTotal(AdjustmentInterface $adjustment): void
404
    {
405
        if (!$adjustment->isNeutral()) {
406
            $this->adjustmentsTotal -= $adjustment->getAmount();
407
            $this->recalculateTotal();
408
        }
409
    }
410
}
411