Completed
Push — master ( 3ecbe1...f7c2f1 )
by Jan
04:05
created

InstockTrait   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 146
rs 10
wmc 14

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getPartUnit() 0 3 1
A setMinAmount() 0 4 1
A setPartUnit() 0 4 1
A addPartLot() 0 5 1
A getAmountSum() 0 18 4
A getMinAmount() 0 7 2
A useFloatAmount() 0 8 2
A removePartLot() 0 4 1
A getPartLots() 0 3 1
1
<?php
2
/**
3
 *
4
 * part-db version 0.1
5
 * Copyright (C) 2005 Christoph Lechner
6
 * http://www.cl-projects.de/
7
 *
8
 * part-db version 0.2+
9
 * Copyright (C) 2009 K. Jacobs and others (see authors.php)
10
 * http://code.google.com/p/part-db/
11
 *
12
 * Part-DB Version 0.4+
13
 * Copyright (C) 2016 - 2019 Jan Böhmer
14
 * https://github.com/jbtronics
15
 *
16
 * This program is free software; you can redistribute it and/or
17
 * modify it under the terms of the GNU General Public License
18
 * as published by the Free Software Foundation; either version 2
19
 * of the License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
29
 *
30
 */
31
32
namespace App\Entity\Parts\PartTraits;
33
34
35
use App\Entity\Parts\MeasurementUnit;
36
use App\Entity\Parts\Part;
37
use App\Entity\Parts\PartLot;
38
use App\Security\Annotations\ColumnSecurity;
39
use Doctrine\Common\Collections\Collection;
40
41
/**
42
 * This trait collects all aspects of a part related to instock, part lots.
43
 * @package App\Entity\Parts\PartTraits
44
 */
45
trait InstockTrait
46
{
47
    /**
48
     * @var ?PartLot[]|Collection A list of part lots where this part is stored
49
     * @ORM\OneToMany(targetEntity="PartLot", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=false)
50
     * @Assert\Valid()
51
     * @ColumnSecurity(type="collection", prefix="lots")
52
     */
53
    protected $partLots;
54
55
    /**
56
     * @var float The minimum amount of the part that has to be instock, otherwise more is ordered.
57
     * Given in the partUnit.
58
     * @ORM\Column(type="float")
59
     * @Assert\PositiveOrZero()
60
     * @ColumnSecurity(prefix="mininstock", type="integer")
61
     */
62
    protected $minamount = 0;
63
64
    /**
65
     * @var ?MeasurementUnit The unit in which the part's amount is measured.
66
     * @ORM\ManyToOne(targetEntity="MeasurementUnit", inversedBy="parts")
67
     * @ORM\JoinColumn(name="id_part_unit", referencedColumnName="id", nullable=true)
68
     * @ColumnSecurity(type="object", prefix="unit")
69
     */
70
    protected $partUnit;
71
72
    /**
73
     * Get all part lots where this part is stored.
74
     * @return PartLot[]|Collection
75
     */
76
    public function getPartLots() : Collection
77
    {
78
        return $this->partLots;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->partLots could return the type App\Entity\Parts\PartLot[]|null which is incompatible with the type-hinted return Doctrine\Common\Collections\Collection. Consider adding an additional type-check to rule them out.
Loading history...
79
    }
80
81
    /**
82
     * Adds the given part lot, to the list of part lots.
83
     * The part lot is assigned to this part.
84
     * @param PartLot $lot
85
     * @return self
86
     */
87
    public function addPartLot(PartLot $lot): self
88
    {
89
        $lot->setPart($this);
90
        $this->partLots->add($lot);
0 ignored issues
show
Bug introduced by
The method add() does not exist on null. ( Ignorable by Annotation )

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

90
        $this->partLots->/** @scrutinizer ignore-call */ 
91
                         add($lot);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
        return $this;
92
    }
93
94
    /**
95
     * Removes the given part lot from the list of part lots.
96
     * @param PartLot $lot The part lot that should be deleted.
97
     * @return self
98
     */
99
    public function removePartLot(PartLot $lot): self
100
    {
101
        $this->partLots->removeElement($lot);
102
        return $this;
103
    }
104
105
    /**
106
     * Gets the measurement unit in which the part's amount should be measured.
107
     * Returns null if no specific unit was that. That means the parts are measured simply in quantity numbers.
108
     * @return MeasurementUnit|null
109
     */
110
    public function getPartUnit(): ?MeasurementUnit
111
    {
112
        return $this->partUnit;
113
    }
114
115
    /**
116
     * Sets the measurement unit in which the part's amount should be measured.
117
     * Set to null, if the part should be measured in quantities.
118
     * @param MeasurementUnit|null $partUnit
119
     * @return self
120
     */
121
    public function setPartUnit(?MeasurementUnit $partUnit): self
122
    {
123
        $this->partUnit = $partUnit;
124
        return $this;
125
    }
126
127
    /**
128
     *  Get the count of parts which must be in stock at least.
129
     * If a integer-based part unit is selected, the value will be rounded to integers
130
     *
131
     * @return float count of parts which must be in stock at least
132
     */
133
    public function getMinAmount(): float
134
    {
135
        if ($this->useFloatAmount()) {
136
            return $this->minamount;
137
        }
138
139
        return round($this->minamount);
140
    }
141
142
    /**
143
     * Checks if this part uses the float amount .
144
     * This setting is based on the part unit (see MeasurementUnit->isInteger()).
145
     * @return bool True if the float amount field should be used. False if the integer instock field should be used.
146
     */
147
    public function useFloatAmount(): bool
148
    {
149
        if ($this->partUnit instanceof MeasurementUnit) {
150
            return !$this->partUnit->isInteger();
151
        }
152
153
        //When no part unit is set, treat it as part count, and so use the integer value.
154
        return false;
155
    }
156
157
    /**
158
     * Returns the summed amount of this part (over all part lots)
159
     * @return float The amount of parts given in partUnit
160
     */
161
    public function getAmountSum() : float
162
    {
163
        //TODO: Find a method to do this natively in SQL, the current method could be a bit slow
164
        $sum = 0;
165
        foreach ($this->getPartLots() as $lot) {
166
            //Dont use the instock value, if it is unkown
167
            if ($lot->isInstockUnknown()) {
168
                continue;
169
            }
170
171
            $sum += $lot->getAmount();
172
        }
173
174
        if ($this->useFloatAmount()) {
175
            return $sum;
176
        }
177
178
        return round($sum);
179
    }
180
181
    /**
182
     * Set the minimum amount of parts that have to be instock.
183
     * See getPartUnit() for the associated unit.
184
     * @param int $new_minamount the new count of parts which should be in stock at least
185
     * @return self
186
     */
187
    public function setMinAmount(float $new_minamount): self
188
    {
189
        $this->minamount = $new_minamount;
190
        return $this;
191
    }
192
}
193