Completed
Push — master ( c4fe9d...e2b643 )
by Jan
03:51
created

Part::getMasterPictureAttachment()   A

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
 *
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
declare(strict_types=1);
33
34
/**
35
 * part-db version 0.1
36
 * Copyright (C) 2005 Christoph Lechner
37
 * http://www.cl-projects.de/.
38
 *
39
 * part-db version 0.2+
40
 * Copyright (C) 2009 K. Jacobs and others (see authors.php)
41
 * http://code.google.com/p/part-db/
42
 *
43
 * Part-DB Version 0.4+
44
 * Copyright (C) 2016 - 2019 Jan Böhmer
45
 * https://github.com/jbtronics
46
 *
47
 * This program is free software; you can redistribute it and/or
48
 * modify it under the terms of the GNU General Public License
49
 * as published by the Free Software Foundation; either version 2
50
 * of the License, or (at your option) any later version.
51
 *
52
 * This program is distributed in the hope that it will be useful,
53
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
54
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
55
 * GNU General Public License for more details.
56
 *
57
 * You should have received a copy of the GNU General Public License
58
 * along with this program; if not, write to the Free Software
59
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
60
 */
61
62
namespace App\Entity\Parts;
63
64
use App\Entity\Attachments\Attachment;
65
use App\Entity\Attachments\AttachmentContainingDBElement;
66
use App\Entity\Devices\Device;
67
use App\Entity\PriceInformations\Orderdetail;
68
use App\Security\Annotations\ColumnSecurity;
69
use App\Validator\Constraints\Selectable;
70
use Doctrine\Common\Collections\ArrayCollection;
71
use Doctrine\Common\Collections\Collection;
72
use Doctrine\ORM\Mapping as ORM;
73
74
use Symfony\Component\Validator\Constraints as Assert;
75
76
/**
77
 * Class Part.
78
 *
79
 * @ORM\Entity(repositoryClass="App\Repository\PartRepository")
80
 * @ORM\Table("`parts`")
81
 */
82
class Part extends AttachmentContainingDBElement
83
{
84
    public const INSTOCK_UNKNOWN = -2;
85
86
    /**
87
     * @ORM\OneToMany(targetEntity="App\Entity\Attachments\PartAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
88
     * @Assert\Valid()
89
     */
90
    protected $attachments;
91
92
    /**
93
     * @var Category
94
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="parts")
95
     * @ORM\JoinColumn(name="id_category", referencedColumnName="id", nullable=false)
96
     * @Selectable()
97
     */
98
    protected $category;
99
100
    /**
101
     * @var Footprint|null
102
     * @ORM\ManyToOne(targetEntity="Footprint", inversedBy="parts")
103
     * @ORM\JoinColumn(name="id_footprint", referencedColumnName="id")
104
     *
105
     * @ColumnSecurity(prefix="footprint", type="object")
106
     * @Selectable()
107
     */
108
    protected $footprint;
109
110
    /**
111
     * @var Manufacturer|null
112
     * @ORM\ManyToOne(targetEntity="Manufacturer", inversedBy="parts")
113
     * @ORM\JoinColumn(name="id_manufacturer", referencedColumnName="id")
114
     *
115
     * @ColumnSecurity(prefix="manufacturer", type="object")
116
     * @Selectable()
117
     */
118
    protected $manufacturer;
119
120
    /**
121
     * @var Attachment
122
     * @ORM\ManyToOne(targetEntity="App\Entity\Attachments\Attachment")
123
     * @ORM\JoinColumn(name="id_master_picture_attachement", referencedColumnName="id")
124
     * @Assert\Expression("value == null or value.isPicture()")
125
     * @ColumnSecurity(prefix="attachments", type="object")
126
     */
127
    protected $master_picture_attachment;
128
129
    /**
130
     * @var Orderdetail[]
131
     * @ORM\OneToMany(targetEntity="App\Entity\PriceInformations\Orderdetail", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
132
     * @Assert\Valid()
133
     * @ColumnSecurity(prefix="orderdetails", type="object")
134
     */
135
    protected $orderdetails;
136
137
    /**
138
     * @var Orderdetail
139
     * @ORM\OneToOne(targetEntity="App\Entity\PriceInformations\Orderdetail")
140
     * @ORM\JoinColumn(name="order_orderdetails_id", referencedColumnName="id")
141
     *
142
     * @ColumnSecurity(prefix="order", type="object")
143
     */
144
    protected $order_orderdetail;
145
146
    //TODO
147
    protected $devices;
148
149
    /**
150
     *  @ColumnSecurity(type="datetime")
151
     * @ORM\Column(type="datetime", name="datetime_added", options={"default"="CURRENT_TIMESTAMP"})
152
     */
153
    protected $addedDate;
154
155
    /**
156
     * @var \DateTime The date when this element was modified the last time.
157
     * @ColumnSecurity(type="datetime")
158
     * @ORM\Column(type="datetime", name="last_modified", options={"default"="CURRENT_TIMESTAMP"})
159
     */
160
    protected $lastModified;
161
162
    /**********************
163
     * Propertys
164
     ***********************/
165
166
    /**
167
     * @var string
168
     * @ORM\Column(type="string")
169
     *
170
     * @ColumnSecurity(prefix="name")
171
     */
172
    protected $name = '';
173
174
    /**
175
     * @var string
176
     * @ORM\Column(type="text")
177
     *
178
     * @ColumnSecurity(prefix="description")
179
     */
180
    protected $description = '';
181
182
    /**
183
     * @var ?PartLot[]
184
     * @ORM\OneToMany(targetEntity="PartLot", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true)
185
     * @Assert\Valid()
186
     */
187
    protected $partLots;
188
189
    /**
190
     * @var float
191
     * @ORM\Column(type="float")
192
     * @Assert\PositiveOrZero()
193
     *
194
     * @ColumnSecurity(prefix="mininstock", type="integer")
195
     */
196
    protected $minamount = 0;
197
198
    /**
199
     * @var string
200
     * @ORM\Column(type="text")
201
     * @ColumnSecurity(prefix="comment")
202
     */
203
    protected $comment = '';
204
205
    /**
206
     * @var bool
207
     * @ORM\Column(type="boolean")
208
     */
209
    protected $visible = true;
210
211
    /**
212
     * @var bool
213
     * @ORM\Column(type="boolean")
214
     * @ColumnSecurity(type="boolean")
215
     */
216
    protected $favorite = false;
217
218
    /**
219
     * @var int
220
     * @ORM\Column(type="integer")
221
     * @ColumnSecurity(prefix="order", type="integer")
222
     */
223
    protected $order_quantity = 0;
224
225
    /**
226
     * @var bool
227
     * @ORM\Column(type="boolean")
228
     * @ColumnSecurity(prefix="order", type="boolean")
229
     */
230
    protected $manual_order = false;
231
232
    /**
233
     * @var string
234
     * @ORM\Column(type="string")
235
     * @Assert\Url()
236
     * @ColumnSecurity(prefix="manufacturer", type="string", placeholder="")
237
     */
238
    protected $manufacturer_product_url = '';
239
240
    /**
241
     * @var string
242
     * @ORM\Column(type="string")
243
     * @ColumnSecurity(prefix="manufacturer", type="string", placeholder="")
244
     */
245
    protected $manufacturer_product_number = '';
246
247
    /**
248
     * @var string
249
     * @ORM\Column(type="string", length=255, nullable=true)
250
     * @Assert\Choice({"announced", "active", "nrfnd", "eol", "discontinued", ""})
251
     */
252
    protected $manufacturing_status = "";
253
254
    /**
255
     * @var bool Determines if this part entry needs review (for example, because it is work in progress)
256
     * @ORM\Column(type="boolean")
257
     */
258
    protected $needs_review = false;
259
260
    /**
261
     * @var ?MeasurementUnit The unit in which the part's amount is measured.
262
     * @ORM\ManyToOne(targetEntity="MeasurementUnit")
263
     * @ORM\JoinColumn(name="id_part_unit", referencedColumnName="id", nullable=true)
264
     */
265
    protected $partUnit;
266
267
    /**
268
     * @var string A comma seperated list of tags, assocciated with the part.
269
     * @ORM\Column(type="text")
270
     */
271
    protected $tags = '';
272
273
    /**
274
     * @var float|null How much a single part unit weighs in gramms.
275
     * @ORM\Column(type="float", nullable=true)
276
     * @Assert\PositiveOrZero()
277
     */
278
    protected $mass;
279
280
    public function __construct()
281
    {
282
        parent::__construct();
283
        $this->partLots = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\Common\Collections\ArrayCollection() of type Doctrine\Common\Collections\ArrayCollection is incompatible with the declared type App\Entity\Parts\PartLot[]|null of property $partLots.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
284
        $this->orderdetails = new ArrayCollection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\Common\Collections\ArrayCollection() of type Doctrine\Common\Collections\ArrayCollection is incompatible with the declared type App\Entity\PriceInformations\Orderdetail[] of property $orderdetails.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
285
    }
286
287
    /**
288
     * Returns the ID as an string, defined by the element class.
289
     * This should have a form like P000014, for a part with ID 14.
290
     *
291
     * @return string The ID as a string;
292
     */
293
    public function getIDString(): string
294
    {
295
        return 'P' . sprintf('%06d', $this->getID());
296
    }
297
298
    /*********************************************************************************
299
     * Getters
300
     ********************************************************************************/
301
302
    /**
303
     * Get the description string like it is saved in the database.
304
     * This can contain BBCode, it is not parsed yet.
305
     *
306
     * @return string the description
307
     */
308
    public function getDescription(): string
309
    {
310
        return  htmlspecialchars($this->description);
311
    }
312
313
    /**
314
     *  Get the count of parts which must be in stock at least.
315
     * If a integer-based part unit is selected, the value will be rounded to integers
316
     *
317
     * @return float count of parts which must be in stock at least
318
     */
319
    public function getMinAmount(): float
320
    {
321
        if ($this->useFloatAmount()) {
322
            return $this->minamount;
323
        }
324
325
        return round($this->minamount);
326
327
    }
328
329
    /**
330
     *  Get the comment associated with this part.
331
     *
332
     * @return string The raw/unparsed comment
333
     */
334
    public function getComment(): string
335
    {
336
        return htmlspecialchars($this->comment);
337
    }
338
339
    /**
340
     *  Get if this part is obsolete.
341
     *
342
     *     A Part is marked as "obsolete" if all their orderdetails are marked as "obsolete".
343
     *          If a part has no orderdetails, the part isn't marked as obsolete.
344
     *
345
     * @return bool true, if this part is obsolete. false, if this part isn't obsolete
346
     */
347
    public function isObsolete(): bool
348
    {
349
        $all_orderdetails = $this->getOrderdetails();
350
351
        if (0 === count($all_orderdetails)) {
352
            return false;
353
        }
354
355
        foreach ($all_orderdetails as $orderdetails) {
356
            if (!$orderdetails->getObsolete()) {
357
                return false;
358
            }
359
        }
360
361
        return true;
362
    }
363
364
    /**
365
     *  Get if this part is visible.
366
     *
367
     * @return bool true if this part is visible
368
     *              false if this part isn't visible
369
     */
370
    public function isVisible(): bool
371
    {
372
        return $this->visible;
373
    }
374
375
    /**
376
     * Get if this part is a favorite.
377
     *
378
     * @return bool * true if this part is a favorite
379
     *              * false if this part is not a favorite.
380
     */
381
    public function isFavorite(): bool
382
    {
383
        return $this->favorite;
384
    }
385
386
    /**
387
     *  Get the selected order orderdetails of this part.
388
     * @return Orderdetail the selected order orderdetails
389
     */
390
    public function getOrderOrderdetails(): ?Orderdetail
391
    {
392
        return $this->order_orderdetail;
393
    }
394
395
    /**
396
     *  Get the order quantity of this part.
397
     *
398
     * @return int the order quantity
399
     */
400
    public function getOrderQuantity(): int
401
    {
402
        return $this->order_quantity;
403
    }
404
405
    /**
406
     *  Check if this part is marked for manual ordering.
407
     *
408
     * @return bool the "manual_order" attribute
409
     */
410
    public function isMarkedForManualOrder(): bool
411
    {
412
        return $this->manual_order;
413
    }
414
415
    /**
416
     *  Get the link to the website of the article on the manufacturers website
417
     *  When no this part has no explicit url set, then it is tried to generate one from the Manufacturer of this part
418
     *  automatically.
419
     *
420
     * @param
421
     *
422
     * @return string the link to the article
423
     */
424
    public function getManufacturerProductUrl(): string
425
    {
426
        if ('' !== $this->manufacturer_product_url) {
427
            return $this->manufacturer_product_url;
428
        }
429
430
        if (null !== $this->getManufacturer()) {
431
            return $this->getManufacturer()->getAutoProductUrl($this->name);
432
        }
433
434
        return ''; // no url is available
435
    }
436
437
    /**
438
     * Similar to getManufacturerProductUrl, but here only the database value is returned.
439
     *
440
     * @return string The manufacturer url saved in DB for this part.
441
     */
442
    public function getCustomProductURL(): string
443
    {
444
        return $this->manufacturer_product_url;
445
    }
446
447
    /**
448
     * Returns the manufacturing/production status for this part.
449
     * The status can be one of the following:
450
     * (Similar to https://designspark.zendesk.com/hc/en-us/articles/213584805-What-are-the-Lifecycle-Status-definitions-)
451
     * * "": Status unknown
452
     * * "announced": Part has been announced, but is not in production yet
453
     * * "active": Part is in production and will be for the forseeable future
454
     * * "nrfnd": Not recommended for new designs.
455
     * * "eol": Part will become discontinued soon
456
     * * "discontinued": Part is obsolete/discontinued by the manufacturer
457
     * @return string
458
     */
459
    public function getManufacturingStatus(): ?string
460
    {
461
        return $this->manufacturing_status;
462
    }
463
464
    /**
465
     * Sets the manufacturing status for this part
466
     * See getManufacturingStatus() for valid values.
467
     * @param string $manufacturing_status
468
     * @return Part
469
     */
470
    public function setManufacturingStatus(string $manufacturing_status): Part
471
    {
472
        $this->manufacturing_status = $manufacturing_status;
473
        return $this;
474
    }
475
476
477
478
    /**
479
     *  Get the category of this part.
480
     *
481
     * There is always a category, for each part!
482
     *
483
     * @return Category the category of this part
484
     */
485
    public function getCategory(): Category
486
    {
487
        return $this->category;
488
    }
489
490
    /**
491
     *  Get the footprint of this part (if there is one).
492
     *
493
     * @return Footprint the footprint of this part (if there is one)
494
     */
495
    public function getFootprint(): ?Footprint
496
    {
497
        return $this->footprint;
498
    }
499
500
    /**
501
     *  Get the manufacturer of this part (if there is one).
502
     *
503
     * @return Manufacturer the manufacturer of this part (if there is one)
504
     */
505
    public function getManufacturer(): ?Manufacturer
506
    {
507
        return $this->manufacturer;
508
    }
509
510
    /**
511
     *  Get the master picture "Attachment"-object of this part (if there is one).
512
     *  The master picture should be used as a visual description/representation of this part.
513
     *
514
     * @return Attachment the master picture Attachement of this part (if there is one)
515
     */
516
    public function getMasterPictureAttachment(): ?Attachment
517
    {
518
        return $this->master_picture_attachment;
519
    }
520
521
    /**
522
     * Sets the new master picture for this part.
523
     * @param Attachment|null $new_master_attachment
524
     * @return Part
525
     */
526
    public function setMasterPictureAttachment(?Attachment $new_master_attachment): Part
527
    {
528
        $this->master_picture_attachment = $new_master_attachment;
529
        return $this;
530
    }
531
532
    /**
533
     *  Get all orderdetails of this part.
534
     *
535
     * @param bool $hide_obsolete If true, obsolete orderdetails will NOT be returned
536
     *
537
     * @return Collection|Orderdetail[] * all orderdetails as a one-dimensional array of Orderdetails objects
538
     *                        (empty array if there are no ones)
539
     *                        * the array is sorted by the suppliers names / minimum order quantity
540
     *
541
     */
542
    public function getOrderdetails(bool $hide_obsolete = false) : Collection
543
    {
544
        //If needed hide the obsolete entries
545
        if ($hide_obsolete) {
546
            $orderdetails = $this->orderdetails;
547
            foreach ($orderdetails as $key => $details) {
548
                if ($details->getObsolete()) {
549
                    unset($orderdetails[$key]);
550
                }
551
            }
552
553
            return $orderdetails;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $orderdetails returns the type App\Entity\PriceInformations\Orderdetail[] which is incompatible with the type-hinted return Doctrine\Common\Collections\Collection.
Loading history...
554
        }
555
556
        return $this->orderdetails;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->orderdetails returns the type App\Entity\PriceInformations\Orderdetail[] which is incompatible with the type-hinted return Doctrine\Common\Collections\Collection.
Loading history...
557
    }
558
559
    public function addOrderdetail(Orderdetail $orderdetail) : Part
560
    {
561
        $orderdetail->setPart($this);
562
        $this->orderdetails->add($orderdetail);
563
        return $this;
564
    }
565
566
    public function removeOrderdetail(Orderdetail $orderdetail) : Part
567
    {
568
        $this->orderdetails->removeElement($orderdetail);
569
        return $this;
570
    }
571
572
    /**
573
     *  Get all devices which uses this part.
574
     *
575
     * @return Device[] * all devices which uses this part as a one-dimensional array of Device objects
576
     *                  (empty array if there are no ones)
577
     *                  * the array is sorted by the devices names
578
     *
579
     */
580
    public function getDevices(): array
581
    {
582
        return $this->devices;
583
    }
584
585
    /**
586
     * Checks if this part is marked, for that it needs further review.
587
     * @return bool
588
     */
589
    public function isNeedsReview(): bool
590
    {
591
        return $this->needs_review;
592
    }
593
594
    /**
595
     * Sets the "needs review" status of this part.
596
     * @param bool $needs_review
597
     * @return Part
598
     */
599
    public function setNeedsReview(bool $needs_review): Part
600
    {
601
        $this->needs_review = $needs_review;
602
        return $this;
603
    }
604
605
    /**
606
     * Get all part lots where this part is stored.
607
     * @return PartLot[]|Collection
608
     */
609
    public function getPartLots() : Collection
610
    {
611
        return $this->partLots;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->partLots returns the type App\Entity\Parts\PartLot[]|null which is incompatible with the type-hinted return Doctrine\Common\Collections\Collection.
Loading history...
612
    }
613
614
    public function addPartLot(PartLot $lot): Part
615
    {
616
        $lot->setPart($this);
617
        $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

617
        $this->partLots->/** @scrutinizer ignore-call */ 
618
                         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...
618
        return $this;
619
    }
620
621
    public function removePartLot(PartLot $lot): Part
622
    {
623
        $this->partLots->removeElement($lot);
624
        return $this;
625
    }
626
627
    /**
628
     * Returns the assigned manufacturer product number (MPN) for this part.
629
     * @return string
630
     */
631
    public function getManufacturerProductNumber(): string
632
    {
633
        return $this->manufacturer_product_number;
634
    }
635
636
    /**
637
     * Sets the manufacturer product number (MPN) for this part.
638
     * @param string $manufacturer_product_number
639
     * @return Part
640
     */
641
    public function setManufacturerProductNumber(string $manufacturer_product_number): Part
642
    {
643
        $this->manufacturer_product_number = $manufacturer_product_number;
644
        return $this;
645
    }
646
647
    /**
648
     * Gets the measurement unit in which the part's amount should be measured.
649
     * Returns null if no specific unit was that. That means the parts are measured simply in quantity numbers.
650
     * @return MeasurementUnit|null
651
     */
652
    public function getPartUnit(): ?MeasurementUnit
653
    {
654
        return $this->partUnit;
655
    }
656
657
    /**
658
     * Sets the measurement unit in which the part's amount should be measured.
659
     * Set to null, if the part should be measured in quantities.
660
     * @param MeasurementUnit|null $partUnit
661
     * @return Part
662
     */
663
    public function setPartUnit(?MeasurementUnit $partUnit): Part
664
    {
665
        $this->partUnit = $partUnit;
666
        return $this;
667
    }
668
669
    /**
670
     * Gets a comma separated list, of tags, that are assigned to this part
671
     * @return string
672
     */
673
    public function getTags(): string
674
    {
675
        return $this->tags;
676
    }
677
678
    /**
679
     * Sets a comma separated list of tags, that are assigned to this part.
680
     * @param string $tags
681
     * @return Part
682
     */
683
    public function setTags(string $tags): Part
684
    {
685
        $this->tags = $tags;
686
        return $this;
687
    }
688
689
    /**
690
     * Returns the mass of a single part unit.
691
     * Returns null, if the mass is unknown/not set yet
692
     * @return float|null
693
     */
694
    public function getMass(): ?float
695
    {
696
        return $this->mass;
697
    }
698
699
    /**
700
     * Sets the mass of a single part unit.
701
     * Sett to null, if the mass is unknown.
702
     * @param float|null $mass
703
     * @return Part
704
     */
705
    public function setMass(?float $mass): Part
706
    {
707
        $this->mass = $mass;
708
        return $this;
709
    }
710
711
    /**
712
     * Checks if this part uses the float amount .
713
     * This setting is based on the part unit (see MeasurementUnit->isInteger()).
714
     * @return bool True if the float amount field should be used. False if the integer instock field should be used.
715
     */
716
    public function useFloatAmount(): bool
717
    {
718
        if ($this->partUnit instanceof MeasurementUnit) {
719
            return !$this->partUnit->isInteger();
720
        }
721
722
        //When no part unit is set, treat it as part count, and so use the integer value.
723
        return false;
724
    }
725
726
    /**
727
     * Returns the summed amount of this part (over all part lots)
728
     * @return float
729
     */
730
    public function getAmountSum() : float
731
    {
732
        //TODO: Find a method to do this natively in SQL, the current method could be a bit slow
733
        $sum = 0;
734
        foreach ($this->getPartLots() as $lot) {
735
            //Dont use the instock value, if it is unkown
736
            if ($lot->isInstockUnknown()) {
737
                continue;
738
            }
739
740
            $sum += $lot->getAmount();
741
        }
742
743
        if ($this->useFloatAmount()) {
744
            return $sum;
745
        }
746
747
        return round($sum);
748
    }
749
750
    /********************************************************************************
751
     *
752
     *   Setters
753
     *
754
     *********************************************************************************/
755
756
    /**
757
     *  Set the description.
758
     *
759
     * @param string $new_description the new description
760
     *
761
     * @return self
762
     */
763
    public function setDescription(?string $new_description): self
764
    {
765
        $this->description = $new_description;
766
767
        return $this;
768
    }
769
770
    /**
771
     *  Set the minimum amount of parts that have to be instock.
772
     *  See getPartUnit() for the associated unit.
773
     *
774
     * @param int $new_minamount the new count of parts which should be in stock at least
775
     *
776
     * @return self
777
     */
778
    public function setMinAmount(float $new_minamount): self
779
    {
780
        //Assert::natural($new_mininstock, 'The new minimum instock value must be positive! Got %s.');
781
782
        $this->minamount = $new_minamount;
783
784
        return $this;
785
    }
786
787
    /**
788
     *  Set the comment.
789
     *
790
     * @param string $new_comment the new comment
791
     *
792
     * @return self
793
     */
794
    public function setComment(string $new_comment): self
795
    {
796
        $this->comment = $new_comment;
797
798
        return $this;
799
    }
800
801
    /**
802
     *  Set the "manual_order" attribute.
803
     *
804
     * @param bool     $new_manual_order          the new "manual_order" attribute
805
     * @param int      $new_order_quantity        the new order quantity
806
     * @param int|null $new_order_orderdetails_id * the ID of the new order orderdetails
807
     *                                            * or Zero for "no order orderdetails"
808
     *                                            * or NULL for automatic order orderdetails
809
     *                                            (if the part has exactly one orderdetails,
810
     *                                            set this orderdetails as order orderdetails.
811
     *                                            Otherwise, set "no order orderdetails")
812
     *
813
     * @return self
814
     */
815
    public function setManualOrder(bool $new_manual_order, int $new_order_quantity = 1, ?Orderdetail $new_order_orderdetail = null): Part
816
    {
817
        //Assert::greaterThan($new_order_quantity, 0, 'The new order quantity must be greater zero. Got %s!');
818
819
        $this->manual_order = $new_manual_order;
820
821
        //TODO;
822
        $this->order_orderdetail = $new_order_orderdetail;
823
        $this->order_quantity = $new_order_quantity;
824
825
        return $this;
826
    }
827
828
    /**
829
     *  Set the category of this Part.
830
     *
831
     *     Every part must have a valid category (in contrast to the
832
     *          attributes "footprint", "storelocation", ...)!
833
     *
834
     * @param Category $category The new category of this part
835
     *
836
     * @return self
837
     */
838
    public function setCategory(Category $category): Part
839
    {
840
        $this->category = $category;
841
842
        return $this;
843
    }
844
845
    /**
846
     * Set the new Footprint of this Part.
847
     *
848
     * @param Footprint|null $new_footprint The new footprint of this part. Set to null, if this part should not have
849
     *                                      a footprint.
850
     *
851
     * @return self
852
     */
853
    public function setFootprint(?Footprint $new_footprint): Part
854
    {
855
        $this->footprint = $new_footprint;
856
857
        return $this;
858
    }
859
860
    /**
861
     * Sets the new manufacturer of this part.
862
     *
863
     * @param Manufacturer|null $new_manufacturer The new Manufacturer of this part. Set to null, if this part should
864
     *                                            not have a manufacturer.
865
     *
866
     * @return Part
867
     */
868
    public function setManufacturer(?Manufacturer $new_manufacturer): self
869
    {
870
        $this->manufacturer = $new_manufacturer;
871
872
        return $this;
873
    }
874
875
    /**
876
     * Set the favorite status for this part.
877
     *
878
     * @param $new_favorite_status bool The new favorite status, that should be applied on this part.
879
     *      Set this to true, when the part should be a favorite.
880
     *
881
     * @return self
882
     */
883
    public function setFavorite(bool $new_favorite_status): self
884
    {
885
        $this->favorite = $new_favorite_status;
886
887
        return $this;
888
    }
889
890
    /**
891
     * Sets the URL to the manufacturer site about this Part. Set to "" if this part should use the automatically URL based on its manufacturer.
892
     *
893
     * @param string $new_url The new url
894
     *
895
     * @return self
896
     */
897
    public function setManufacturerProductURL(string $new_url): self
898
    {
899
        $this->manufacturer_product_url = $new_url;
900
901
        return $this;
902
    }
903
}
904