Part-DB.Part-DB-server/src/Entity/Parts/PartLot.php

312 lines
8.2 KiB
PHP
Raw Normal View History

<?php
2020-02-22 18:14:36 +01:00
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
2022-11-29 22:28:53 +01:00
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
2020-02-22 18:14:36 +01:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2020-01-05 15:46:58 +01:00
declare(strict_types=1);
namespace App\Entity\Parts;
use App\Entity\Base\AbstractDBElement;
use App\Entity\Base\TimestampTrait;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\Contracts\TimeStampableInterface;
use App\Validator\Constraints\Selectable;
use App\Validator\Constraints\ValidPartLot;
2020-01-05 22:49:00 +01:00
use DateTime;
use Doctrine\ORM\Mapping as ORM;
2020-01-05 22:49:00 +01:00
use Exception;
2023-03-12 01:12:35 +01:00
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* This entity describes a lot where parts can be stored.
* It is the connection between a part and its store locations.
*
* @ORM\Entity()
* @ORM\Table(name="part_lots", indexes={
* @ORM\Index(name="part_lots_idx_instock_un_expiration_id_part", columns={"instock_unknown", "expiration_date", "id_part"}),
* @ORM\Index(name="part_lots_idx_needs_refill", columns={"needs_refill"}),
* })
* @ORM\HasLifecycleCallbacks()
* @ValidPartLot()
*/
class PartLot extends AbstractDBElement implements TimeStampableInterface, NamedElementInterface
{
use TimestampTrait;
/**
* @var string A short description about this lot, shown in table
* @ORM\Column(type="text")
2023-03-13 00:52:22 +01:00
* @Groups({"simple", "extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected string $description = '';
/**
2020-08-21 21:36:22 +02:00
* @var string a comment stored with this lot
* @ORM\Column(type="text")
2023-03-13 00:52:22 +01:00
* @Groups({"full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected string $comment = '';
/**
2020-01-05 22:49:00 +01:00
* @var ?DateTime Set a time until when the lot must be used.
* Set to null, if the lot can be used indefinitely.
* @ORM\Column(type="datetime", name="expiration_date", nullable=true)
2023-03-13 00:52:22 +01:00
* @Groups({"extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected ?DateTime $expiration_date = null;
/**
* @var Storelocation|null The storelocation of this lot
* @ORM\ManyToOne(targetEntity="Storelocation")
* @ORM\JoinColumn(name="id_store_location", referencedColumnName="id", nullable=true)
* @Selectable()
2023-03-13 00:52:22 +01:00
* @Groups({"simple", "extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected ?Storelocation $storage_location = null;
/**
* @var bool If this is set to true, the instock amount is marked as not known
* @ORM\Column(type="boolean")
2023-03-13 00:52:22 +01:00
* @Groups({"simple", "extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected bool $instock_unknown = false;
/**
2019-11-10 14:00:56 +01:00
* @var float For continuous sizes (length, volume, etc.) the instock is saved here.
2019-08-16 22:54:23 +02:00
* @ORM\Column(type="float")
* @Assert\PositiveOrZero()
2023-03-13 00:52:22 +01:00
* @Groups({"simple", "extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected float $amount = 0.0;
/**
2020-08-21 21:36:22 +02:00
* @var bool determines if this lot was manually marked for refilling
* @ORM\Column(type="boolean")
2023-03-13 00:52:22 +01:00
* @Groups({"extended", "full", "import"})
*/
2022-09-18 22:59:31 +02:00
protected bool $needs_refill = false;
2020-01-05 22:49:00 +01:00
/**
* @var Part The part that is stored in this lot
2020-05-17 20:49:43 +02:00
* @ORM\ManyToOne(targetEntity="Part", inversedBy="partLots")
2020-01-05 22:49:00 +01:00
* @ORM\JoinColumn(name="id_part", referencedColumnName="id", nullable=false, onDelete="CASCADE")
* @Assert\NotNull()
*/
2022-09-18 22:59:31 +02:00
protected Part $part;
2020-01-05 22:49:00 +01:00
2020-03-15 13:56:31 +01:00
public function __clone()
{
if ($this->id) {
$this->addedDate = null;
}
parent::__clone();
}
2019-08-16 22:54:23 +02:00
/**
* Check if the current part lot is expired.
* This is the case, if the expiration date is greater the the current date.
*
2019-08-16 22:54:23 +02:00
* @return bool|null True, if the part lot is expired. Returns null, if no expiration date was set.
2020-01-04 20:24:09 +01:00
*
2020-01-05 22:49:00 +01:00
* @throws Exception If an error with the DateTime occurs
2019-08-16 22:54:23 +02:00
*/
public function isExpired(): ?bool
{
if (null === $this->expiration_date) {
2019-08-16 22:54:23 +02:00
return null;
}
//Check if the expiration date is bigger then current time
2020-01-05 22:49:00 +01:00
return $this->expiration_date < new DateTime('now');
2019-08-16 22:54:23 +02:00
}
/**
* Gets the description of the part lot. Similar to a "name" of the part lot.
*/
public function getDescription(): string
{
return $this->description;
}
/**
* Sets the description of the part lot.
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
public function setDescription(string $description): self
2019-08-16 22:54:23 +02:00
{
$this->description = $description;
2019-08-16 22:54:23 +02:00
return $this;
}
/**
* Gets the comment for this part lot.
*/
public function getComment(): string
{
return $this->comment;
}
/**
* Sets the comment for this part lot.
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
public function setComment(string $comment): self
2019-08-16 22:54:23 +02:00
{
$this->comment = $comment;
2019-08-16 22:54:23 +02:00
return $this;
}
/**
* Gets the expiration date for the part lot. Returns null, if no expiration date was set.
*/
2020-01-05 22:49:00 +01:00
public function getExpirationDate(): ?DateTime
2019-08-16 22:54:23 +02:00
{
return $this->expiration_date;
}
/**
* Sets the expiration date for the part lot. Set to null, if the part lot does not expires.
*
2022-08-14 19:39:07 +02:00
* @param DateTime|null $expiration_date
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
2020-01-05 22:49:00 +01:00
public function setExpirationDate(?DateTime $expiration_date): self
2019-08-16 22:54:23 +02:00
{
$this->expiration_date = $expiration_date;
2019-08-16 22:54:23 +02:00
return $this;
}
/**
2019-11-10 14:00:56 +01:00
* Gets the storage location, where this part lot is stored.
*
* @return Storelocation|null The store location where this part is stored
2019-08-16 22:54:23 +02:00
*/
public function getStorageLocation(): ?Storelocation
2019-08-16 22:54:23 +02:00
{
return $this->storage_location;
}
/**
* Sets the storage location, where this part lot is stored.
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
public function setStorageLocation(?Storelocation $storage_location): self
2019-08-16 22:54:23 +02:00
{
$this->storage_location = $storage_location;
2019-08-16 22:54:23 +02:00
return $this;
}
/**
* Return the part that is stored in this part lot.
*/
public function getPart(): Part
{
return $this->part;
}
/**
* Sets the part that is stored in this part lot.
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
public function setPart(Part $part): self
2019-08-16 22:54:23 +02:00
{
$this->part = $part;
2019-08-16 22:54:23 +02:00
return $this;
}
/**
* Checks if the instock value in the part lot is unknown.
*/
public function isInstockUnknown(): bool
{
return $this->instock_unknown;
}
/**
* Set the unknown instock status of this part lot.
*
2019-08-16 22:54:23 +02:00
* @return PartLot
*/
public function setInstockUnknown(bool $instock_unknown): self
2019-08-16 22:54:23 +02:00
{
$this->instock_unknown = $instock_unknown;
2019-08-16 22:54:23 +02:00
return $this;
}
public function getAmount(): float
{
2020-08-21 21:36:22 +02:00
if ($this->part instanceof Part && !$this->part->useFloatAmount()) {
2019-08-16 22:54:23 +02:00
return round($this->amount);
}
2022-12-18 19:45:04 +01:00
return $this->amount;
2019-08-16 22:54:23 +02:00
}
/**
* Sets the amount of parts in the part lot.
* If null is passed, amount will be set to unknown.
2020-04-10 13:05:08 +02:00
*
* @return $this
*/
public function setAmount(?float $new_amount): self
2019-08-16 22:54:23 +02:00
{
//Treat null like unknown amount
2020-04-10 13:05:08 +02:00
if (null === $new_amount) {
$this->instock_unknown = true;
$new_amount = 0.0;
}
$this->amount = $new_amount;
return $this;
2019-08-16 22:54:23 +02:00
}
public function isNeedsRefill(): bool
{
return $this->needs_refill;
}
/**
* @return PartLot
*/
public function setNeedsRefill(bool $needs_refill): self
2019-08-16 22:54:23 +02:00
{
$this->needs_refill = $needs_refill;
2019-08-16 22:54:23 +02:00
return $this;
}
public function getName(): string
{
return $this->description;
}
}