OrderLineTrait   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 113
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addStockMovement() 0 18 4
A getStockMovements() 0 6 1
A setStockMovements() 0 8 2
A computeEffectiveStockMovement() 0 21 3
A initStockMovements() 0 6 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Loevgaard\DandomainStock\Entity;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\ORM\Mapping as ORM;
9
use Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface;
10
use Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException;
11
12
trait OrderLineTrait
13
{
14
    /**
15
     * @var StockMovement[]|ArrayCollection
16
     *
17
     * @ORM\OneToMany(targetEntity="Loevgaard\DandomainStock\Entity\StockMovement", mappedBy="orderLine", cascade={"persist"})
18
     */
19
    protected $stockMovements;
20
21
    /**
22
     * @param \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface $stockMovement
23
     *
24
     * @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...
25
     *
26
     * @throws \Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException
27
     */
28
    public function addStockMovement(StockMovementInterface $stockMovement)
29
    {
30
        $this->initStockMovements();
31
32
        if ($this->stockMovements->count()) {
33
            /** @var StockMovement $firstStockMovement */
34
            $firstStockMovement = $this->stockMovements->first();
35
            if ($stockMovement->getProduct()->getId() !== $firstStockMovement->getProduct()->getId()) {
36
                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().'`');
37
            }
38
        }
39
40
        if (!$this->stockMovements->contains($stockMovement)) {
41
            $this->stockMovements->add($stockMovement);
42
        }
43
44
        return $this;
45
    }
46
47
    /**
48
     * @return \Loevgaard\DandomainStock\Entity\StockMovement[]
49
     */
50
    public function getStockMovements()
51
    {
52
        $this->initStockMovements();
53
54
        return $this->stockMovements;
55
    }
56
57
    /**
58
     * @param \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface[] $stockMovements
59
     *
60
     * @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...
61
     *
62
     * @throws \Loevgaard\DandomainStock\Exception\StockMovementProductMismatchException
63
     */
64
    public function setStockMovements($stockMovements)
65
    {
66
        foreach ($stockMovements as $stockMovement) {
67
            $this->addStockMovement($stockMovement);
68
        }
69
70
        return $this;
71
    }
72
73
    /**
74
     * Say you have these two stock movements associated with this order line:.
75
     *
76
     * | qty | product |
77
     * -----------------
78
     * | 1   | Jeans   |
79
     * | -1  | Jeans   |
80
     *
81
     * Then the effective stock movement would be
82
     *
83
     * | qty | product |
84
     * -----------------
85
     * | 0   | Jeans   |
86
     *
87
     * And this is what we return in this method
88
     *
89
     * Returns null if the order line has 0 stock movements
90
     *
91
     * @return \Loevgaard\DandomainStock\Entity\Generated\StockMovementInterface|null
92
     *
93
     * @throws \Loevgaard\DandomainStock\Exception\CurrencyMismatchException
94
     * @throws \Loevgaard\DandomainStock\Exception\UnsetCurrencyException
95
     */
96
    public function computeEffectiveStockMovement(): ?StockMovementInterface
97
    {
98
        $this->initStockMovements();
99
100
        if (!$this->stockMovements->count()) {
101
            return null;
102
        }
103
104
        /** @var StockMovementInterface $lastStockMovement */
105
        $lastStockMovement = $this->stockMovements->last();
106
107
        $qty = 0;
108
        foreach ($this->stockMovements as $stockMovement) {
109
            $qty += $stockMovement->getQuantity();
110
        }
111
112
        $stockMovement = $lastStockMovement->copy();
113
        $stockMovement->setQuantity($qty);
114
115
        return $stockMovement;
116
    }
117
118
    protected function initStockMovements(): void
119
    {
120
        if (is_null($this->stockMovements)) {
121
            $this->stockMovements = new ArrayCollection();
122
        }
123
    }
124
}
125