Completed
Push — master ( 7f0608...cabad0 )
by Joachim
14:08
created

OrderLineTrait::setStockMovements()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Loevgaard\DandomainStock\Entity;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\Mapping as ORM;
7
use Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface;
8
use Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException;
9
10
trait OrderLineTrait
11
{
12
    /**
13
     * @var StockMovement[]|ArrayCollection
14
     *
15
     * @ORM\OneToMany(targetEntity="Loevgaard\DandomainStock\Entity\StockMovement", mappedBy="orderLine", cascade={"persist"})
16
     */
17
    protected $stockMovements;
18
19
    /**
20
     * @param \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface $stockMovement
21
     *
22
     * @return OrderLineTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type OrderLineTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
23
     *
24
     * @throws \Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException
25
     */
26
    public function addStockMovement(StockMovementInterface $stockMovement)
27
    {
28
        $this->initStockMovements();
29
30
        if ($this->stockMovements->count()) {
31
            /** @var StockMovement $firstStockMovement */
32
            $firstStockMovement = $this->stockMovements->first();
33
            if ($stockMovement->getProduct()->getId() !== $firstStockMovement->getProduct()->getId()) {
34
                throw new StockMovementProductMismatchException('The product id of the first product is `'.$firstStockMovement->getProduct()->getId().'` while the one you are adding has this id: `'.$stockMovement->getProduct()->getId().'`');
35
            }
36
        }
37
38
        if (!$this->stockMovements->contains($stockMovement)) {
39
            $this->stockMovements->add($stockMovement);
40
        }
41
42
        return $this;
43
    }
44
45
    /**
46
     * @return \Loevgaard\DandomainStock\Entity\StockMovement[]
47
     */
48
    public function getStockMovements()
49
    {
50
        $this->initStockMovements();
51
52
        return $this->stockMovements;
53
    }
54
55
    /**
56
     * @param \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface[] $stockMovements
57
     *
58
     * @return OrderLineTrait
0 ignored issues
show
Comprehensibility Bug introduced by
The return type OrderLineTrait is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
59
     *
60
     * @throws \Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException
61
     */
62
    public function setStockMovements($stockMovements)
63
    {
64
        foreach ($stockMovements as $stockMovement) {
65
            $this->addStockMovement($stockMovement);
66
        }
67
68
        return $this;
69
    }
70
71
    /**
72
     * Say you have these two stock movements associated with this order line:.
73
     *
74
     * | qty | product |
75
     * -----------------
76
     * | 1   | Jeans   |
77
     * | -1  | Jeans   |
78
     *
79
     * Then the effective stock movement would be
80
     *
81
     * | qty | product |
82
     * -----------------
83
     * | 0   | Jeans   |
84
     *
85
     * And this is what we return in this method
86
     *
87
     * Returns null if the order line has 0 stock movements
88
     *
89
     * @return \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface|null
90
     *
91
     * @throws \Loevgaard\DandomainStock\Exception\CurrencyMismatchException
92
     * @throws \Loevgaard\DandomainStock\Exception\UnsetCurrencyException
93
     */
94
    public function computeEffectiveStockMovement(): ?StockMovementInterface
95
    {
96
        $this->initStockMovements();
97
98
        if (!$this->stockMovements->count()) {
99
            return null;
100
        }
101
102
        /** @var StockMovementInterface $lastStockMovement */
103
        $lastStockMovement = $this->stockMovements->last();
104
105
        $qty = 0;
106
        $stockMovement = $lastStockMovement->copy();
107
108
        foreach ($this->stockMovements as $stockMovement) {
109
            $qty += $stockMovement->getQuantity();
110
        }
111
112
        $stockMovement->setQuantity($qty);
113
114
        return $stockMovement;
115
    }
116
117
    protected function initStockMovements(): void
118
    {
119
        if (!is_null($this->stockMovements)) {
120
            return;
121
        }
122
123
        $this->stockMovements = new ArrayCollection();
124
    }
125
}
126