PartLot::isNeedsRefill()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as published
9
 * by the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
declare(strict_types=1);
22
23
namespace App\Entity\Parts;
24
25
use App\Entity\Base\AbstractDBElement;
26
use App\Entity\Base\TimestampTrait;
27
use App\Entity\Contracts\NamedElementInterface;
28
use App\Entity\Contracts\TimeStampableInterface;
29
use App\Validator\Constraints\Selectable;
30
use App\Validator\Constraints\ValidPartLot;
31
use DateTime;
32
use Doctrine\ORM\Mapping as ORM;
33
use Exception;
34
use Symfony\Component\Validator\Constraints as Assert;
35
36
/**
37
 * This entity describes a lot where parts can be stored.
38
 * It is the connection between a part and its store locations.
39
 *
40
 * @ORM\Entity()
41
 * @ORM\Table(name="part_lots", indexes={
42
 *    @ORM\Index(name="part_lots_idx_instock_un_expiration_id_part", columns={"instock_unknown", "expiration_date", "id_part"}),
43
 *    @ORM\Index(name="part_lots_idx_needs_refill", columns={"needs_refill"}),
44
 * })
45
 * @ORM\HasLifecycleCallbacks()
46
 * @ValidPartLot()
47
 */
48
class PartLot extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
49
{
50
    use TimestampTrait;
51
52
    /**
53
     * @var string A short description about this lot, shown in table
54
     * @ORM\Column(type="text")
55
     */
56
    protected string $description = '';
57
58
    /**
59
     * @var string a comment stored with this lot
60
     * @ORM\Column(type="text")
61
     */
62
    protected string $comment = '';
63
64
    /**
65
     * @var ?DateTime Set a time until when the lot must be used.
66
     *                Set to null, if the lot can be used indefinitely.
67
     * @ORM\Column(type="datetime", name="expiration_date", nullable=true)
68
     */
69
    protected ?DateTime $expiration_date = null;
70
71
    /**
72
     * @var Storelocation|null The storelocation of this lot
73
     * @ORM\ManyToOne(targetEntity="Storelocation")
74
     * @ORM\JoinColumn(name="id_store_location", referencedColumnName="id", nullable=true)
75
     * @Selectable()
76
     */
77
    protected ?Storelocation $storage_location = null;
78
79
    /**
80
     * @var bool If this is set to true, the instock amount is marked as not known
81
     * @ORM\Column(type="boolean")
82
     */
83
    protected bool $instock_unknown = false;
84
85
    /**
86
     * @var float For continuous sizes (length, volume, etc.) the instock is saved here.
87
     * @ORM\Column(type="float")
88
     * @Assert\PositiveOrZero()
89
     */
90
    protected float $amount = 0.0;
91
92
    /**
93
     * @var bool determines if this lot was manually marked for refilling
94
     * @ORM\Column(type="boolean")
95
     */
96
    protected bool $needs_refill = false;
97
98
    /**
99
     * @var Part The part that is stored in this lot
100
     * @ORM\ManyToOne(targetEntity="Part", inversedBy="partLots")
101
     * @ORM\JoinColumn(name="id_part", referencedColumnName="id", nullable=false, onDelete="CASCADE")
102
     * @Assert\NotNull()
103
     */
104
    protected Part $part;
105
106
    public function __clone()
107
    {
108
        if ($this->id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->id of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
109
            $this->addedDate = null;
110
        }
111
        parent::__clone();
112
    }
113
114
    /**
115
     * Check if the current part lot is expired.
116
     * This is the case, if the expiration date is greater the the current date.
117
     *
118
     * @return bool|null True, if the part lot is expired. Returns null, if no expiration date was set.
119
     *
120
     * @throws Exception If an error with the DateTime occurs
121
     */
122
    public function isExpired(): ?bool
123
    {
124
        if (null === $this->expiration_date) {
125
            return null;
126
        }
127
128
        //Check if the expiration date is bigger then current time
129
        return $this->expiration_date < new DateTime('now');
130
    }
131
132
    /**
133
     * Gets the description of the part lot. Similar to a "name" of the part lot.
134
     */
135
    public function getDescription(): string
136
    {
137
        return $this->description;
138
    }
139
140
    /**
141
     * Sets the description of the part lot.
142
     *
143
     * @return PartLot
144
     */
145
    public function setDescription(string $description): self
146
    {
147
        $this->description = $description;
148
149
        return $this;
150
    }
151
152
    /**
153
     * Gets the comment for this part lot.
154
     */
155
    public function getComment(): string
156
    {
157
        return $this->comment;
158
    }
159
160
    /**
161
     * Sets the comment for this part lot.
162
     *
163
     * @return PartLot
164
     */
165
    public function setComment(string $comment): self
166
    {
167
        $this->comment = $comment;
168
169
        return $this;
170
    }
171
172
    /**
173
     * Gets the expiration date for the part lot. Returns null, if no expiration date was set.
174
     */
175
    public function getExpirationDate(): ?DateTime
176
    {
177
        return $this->expiration_date;
178
    }
179
180
    /**
181
     * Sets the expiration date for the part lot. Set to null, if the part lot does not expires.
182
     *
183
     * @param  DateTime|null  $expiration_date
184
     *
185
     * @return PartLot
186
     */
187
    public function setExpirationDate(?DateTime $expiration_date): self
188
    {
189
        $this->expiration_date = $expiration_date;
190
191
        return $this;
192
    }
193
194
    /**
195
     * Gets the storage location, where this part lot is stored.
196
     *
197
     * @return Storelocation|null The store location where this part is stored
198
     */
199
    public function getStorageLocation(): ?Storelocation
200
    {
201
        return $this->storage_location;
202
    }
203
204
    /**
205
     * Sets the storage location, where this part lot is stored.
206
     *
207
     * @return PartLot
208
     */
209
    public function setStorageLocation(?Storelocation $storage_location): self
210
    {
211
        $this->storage_location = $storage_location;
212
213
        return $this;
214
    }
215
216
    /**
217
     * Return the part that is stored in this part lot.
218
     */
219
    public function getPart(): Part
220
    {
221
        return $this->part;
222
    }
223
224
    /**
225
     * Sets the part that is stored in this part lot.
226
     *
227
     * @return PartLot
228
     */
229
    public function setPart(Part $part): self
230
    {
231
        $this->part = $part;
232
233
        return $this;
234
    }
235
236
    /**
237
     * Checks if the instock value in the part lot is unknown.
238
     */
239
    public function isInstockUnknown(): bool
240
    {
241
        return $this->instock_unknown;
242
    }
243
244
    /**
245
     * Set the unknown instock status of this part lot.
246
     *
247
     * @return PartLot
248
     */
249
    public function setInstockUnknown(bool $instock_unknown): self
250
    {
251
        $this->instock_unknown = $instock_unknown;
252
253
        return $this;
254
    }
255
256
    public function getAmount(): float
257
    {
258
        if ($this->part instanceof Part && !$this->part->useFloatAmount()) {
259
            return round($this->amount);
260
        }
261
262
        return $this->amount;
263
    }
264
265
    /**
266
     * Sets the amount of parts in the part lot.
267
     * If null is passed, amount will be set to unknown.
268
     *
269
     * @return $this
270
     */
271
    public function setAmount(?float $new_amount): self
272
    {
273
        //Treat null like unknown amount
274
        if (null === $new_amount) {
275
            $this->instock_unknown = true;
276
            $new_amount = 0.0;
277
        }
278
279
        $this->amount = $new_amount;
280
281
        return $this;
282
    }
283
284
    public function isNeedsRefill(): bool
285
    {
286
        return $this->needs_refill;
287
    }
288
289
    /**
290
     * @return PartLot
291
     */
292
    public function setNeedsRefill(bool $needs_refill): self
293
    {
294
        $this->needs_refill = $needs_refill;
295
296
        return $this;
297
    }
298
299
    public function getName(): string
300
    {
301
        return $this->description;
302
    }
303
}
304