Passed
Branch master (350f1b)
by Jan
04:53
created

PartLot::getIDString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 - 2020 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
/**
24
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
25
 *
26
 * Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
27
 *
28
 * This program is free software; you can redistribute it and/or
29
 * modify it under the terms of the GNU General Public License
30
 * as published by the Free Software Foundation; either version 2
31
 * of the License, or (at your option) any later version.
32
 *
33
 * This program is distributed in the hope that it will be useful,
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
 * GNU General Public License for more details.
37
 *
38
 * You should have received a copy of the GNU General Public License
39
 * along with this program; if not, write to the Free Software
40
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
41
 */
42
43
namespace App\Entity\Parts;
44
45
use App\Entity\Base\AbstractDBElement;
46
use App\Entity\Base\TimestampTrait;
47
use App\Entity\Contracts\NamedElementInterface;
48
use App\Entity\Contracts\TimeStampableInterface;
49
use App\Validator\Constraints\Selectable;
50
use App\Validator\Constraints\ValidPartLot;
51
use DateTime;
52
use Doctrine\ORM\Mapping as ORM;
53
use Exception;
54
use Symfony\Component\Validator\Constraints as Assert;
55
56
/**
57
 * This entity describes a lot where parts can be stored.
58
 * It is the connection between a part and its store locations.
59
 *
60
 * @ORM\Entity()
61
 * @ORM\Table(name="part_lots")
62
 * @ORM\HasLifecycleCallbacks()
63
 * @ValidPartLot()
64
 */
65
class PartLot extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
66
{
67
    use TimestampTrait;
68
69
    /**
70
     * @var string A short description about this lot, shown in table
71
     * @ORM\Column(type="text")
72
     */
73
    protected $description = '';
74
75
    /**
76
     * @var string A comment stored with this lot.
77
     * @ORM\Column(type="text")
78
     */
79
    protected $comment = '';
80
81
    /**
82
     * @var ?DateTime Set a time until when the lot must be used.
83
     *                Set to null, if the lot can be used indefinitely.
84
     * @ORM\Column(type="datetime", name="expiration_date", nullable=true)
85
     */
86
    protected $expiration_date;
87
88
    /**
89
     * @var Storelocation|null The storelocation of this lot
90
     * @ORM\ManyToOne(targetEntity="Storelocation")
91
     * @ORM\JoinColumn(name="id_store_location", referencedColumnName="id", nullable=true)
92
     * @Selectable()
93
     */
94
    protected $storage_location;
95
96
    /**
97
     * @var bool If this is set to true, the instock amount is marked as not known
98
     * @ORM\Column(type="boolean")
99
     */
100
    protected $instock_unknown = false;
101
102
    /**
103
     * @var float For continuous sizes (length, volume, etc.) the instock is saved here.
104
     * @ORM\Column(type="float")
105
     * @Assert\PositiveOrZero()
106
     */
107
    protected $amount = 0;
108
109
    /**
110
     * @var bool Determines if this lot was manually marked for refilling.
111
     * @ORM\Column(type="boolean")
112
     */
113
    protected $needs_refill = false;
114
115
    /**
116
     * @var Part The part that is stored in this lot
117
     * @ORM\ManyToOne(targetEntity="Part", inversedBy="partLots")
118
     * @ORM\JoinColumn(name="id_part", referencedColumnName="id", nullable=false, onDelete="CASCADE")
119
     * @Assert\NotNull()
120
     */
121
    protected $part;
122
123
    public function __clone()
124
    {
125
        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...
126
            $this->addedDate = null;
127
        }
128
        parent::__clone();
129
    }
130
131
132
    /**
133
     * Check if the current part lot is expired.
134
     * This is the case, if the expiration date is greater the the current date.
135
     *
136
     * @return bool|null True, if the part lot is expired. Returns null, if no expiration date was set.
137
     *
138
     * @throws Exception If an error with the DateTime occurs
139
     */
140
    public function isExpired(): ?bool
141
    {
142
        if (null === $this->expiration_date) {
143
            return null;
144
        }
145
146
        //Check if the expiration date is bigger then current time
147
        return $this->expiration_date < new DateTime('now');
148
    }
149
150
    /**
151
     * Gets the description of the part lot. Similar to a "name" of the part lot.
152
     *
153
     * @return string
154
     */
155
    public function getDescription(): string
156
    {
157
        return $this->description;
158
    }
159
160
    /**
161
     * Sets the description of the part lot.
162
     *
163
     * @return PartLot
164
     */
165
    public function setDescription(string $description): self
166
    {
167
        $this->description = $description;
168
169
        return $this;
170
    }
171
172
    /**
173
     * Gets the comment for this part lot.
174
     *
175
     * @return string
176
     */
177
    public function getComment(): string
178
    {
179
        return $this->comment;
180
    }
181
182
    /**
183
     * Sets the comment for this part lot.
184
     *
185
     * @return PartLot
186
     */
187
    public function setComment(string $comment): self
188
    {
189
        $this->comment = $comment;
190
191
        return $this;
192
    }
193
194
    /**
195
     * Gets the expiration date for the part lot. Returns null, if no expiration date was set.
196
     *
197
     * @return DateTime|null
198
     */
199
    public function getExpirationDate(): ?DateTime
200
    {
201
        return $this->expiration_date;
202
    }
203
204
    /**
205
     * Sets the expiration date for the part lot. Set to null, if the part lot does not expires.
206
     *
207
     * @param DateTime $expiration_date
208
     *
209
     * @return PartLot
210
     */
211
    public function setExpirationDate(?DateTime $expiration_date): self
212
    {
213
        $this->expiration_date = $expiration_date;
214
215
        return $this;
216
    }
217
218
    /**
219
     * Gets the storage location, where this part lot is stored.
220
     *
221
     * @return Storelocation|null The store location where this part is stored
222
     */
223
    public function getStorageLocation(): ?Storelocation
224
    {
225
        return $this->storage_location;
226
    }
227
228
    /**
229
     * Sets the storage location, where this part lot is stored.
230
     *
231
     * @return PartLot
232
     */
233
    public function setStorageLocation(?Storelocation $storage_location): self
234
    {
235
        $this->storage_location = $storage_location;
236
237
        return $this;
238
    }
239
240
    /**
241
     * Return the part that is stored in this part lot.
242
     *
243
     * @return Part
244
     */
245
    public function getPart(): Part
246
    {
247
        return $this->part;
248
    }
249
250
    /**
251
     * Sets the part that is stored in this part lot.
252
     *
253
     * @return PartLot
254
     */
255
    public function setPart(Part $part): self
256
    {
257
        $this->part = $part;
258
259
        return $this;
260
    }
261
262
    /**
263
     * Checks if the instock value in the part lot is unknown.
264
     *
265
     * @return bool
266
     */
267
    public function isInstockUnknown(): bool
268
    {
269
        return $this->instock_unknown;
270
    }
271
272
    /**
273
     * Set the unknown instock status of this part lot.
274
     *
275
     * @return PartLot
276
     */
277
    public function setInstockUnknown(bool $instock_unknown): self
278
    {
279
        $this->instock_unknown = $instock_unknown;
280
281
        return $this;
282
    }
283
284
    /**
285
     * @return float
286
     */
287
    public function getAmount(): float
288
    {
289
        if ($this->part instanceof Part && ! $this->part->useFloatAmount()) {
290
            return round($this->amount);
291
        }
292
293
        return (float) $this->amount;
294
    }
295
296
    /**
297
     * Sets the amount of parts in the part lot.
298
     * If null is passed, amount will be set to unknown.
299
     *
300
     * @return $this
301
     */
302
    public function setAmount(?float $new_amount): self
303
    {
304
        //Treat null like unknown amount
305
        if (null === $new_amount) {
306
            $this->instock_unknown = true;
307
            $new_amount = 0.0;
308
        }
309
310
        $this->amount = $new_amount;
311
312
        return $this;
313
    }
314
315
    /**
316
     * @return bool
317
     */
318
    public function isNeedsRefill(): bool
319
    {
320
        return $this->needs_refill;
321
    }
322
323
    /**
324
     * @return PartLot
325
     */
326
    public function setNeedsRefill(bool $needs_refill): self
327
    {
328
        $this->needs_refill = $needs_refill;
329
330
        return $this;
331
    }
332
333
    public function getName(): string
334
    {
335
        return $this->description;
336
    }
337
}
338