<?php
namespace App\Entity;
use App\Repository\ComponentInventoryItemRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(
repositoryClass: ComponentInventoryItemRepository::class
)]
#[ORM\Table(
name: 'component_inventory_item',
options: ['collate' => 'utf8_swedish_ci']
)]
#[ORM\UniqueConstraint(
name: 'product_code',
columns: ['code']
)]
class ComponentInventoryItem implements EntityInterface
{
const TYPE_COMPONENT = 'component';
const TYPE_SALES_ITEM = 'sales_item';
const DESCRIPTION_MAX_LENGTH = 80;
#[ORM\Id]
#[ORM\Column(
type: 'integer'
)]
#[ORM\GeneratedValue(
strategy: 'AUTO'
)]
protected ?int $id = null;
#[ORM\Column(
type: 'string',
length: 100
)]
#[Assert\NotBlank]
protected string $code;
#[ORM\Column(
type: 'string',
length: 80,
nullable: true
)]
protected ?string $description = null;
/**
* @var Collection<ComponentInventoryLogEntry>|null
*/
#[ORM\OneToMany(
mappedBy: 'item',
targetEntity: ComponentInventoryLogEntry::class,
cascade: ['persist', 'remove']
)]
#[ORM\OrderBy(['created' => 'DESC'])]
#[Assert\Valid]
protected ?Collection $logEntries = null;
#[ORM\Column(
type: 'integer'
)]
#[Assert\NotNull]
#[Assert\PositiveOrZero]
protected int $quantity;
#[ORM\Column(
type: 'string',
length: 20,
nullable: true
)]
protected string $type;
/**
* Unit price in euro cents with three decimals.
*/
#[ORM\Column(
type: 'decimal',
precision: 13,
scale: 3,
nullable: true
)]
#[Assert\NotNull]
#[Assert\PositiveOrZero]
protected string $unitPrice;
/**
* @param string $code
* @param int $quantity
* @param float $unitPrice
* @param string|null $description
* @param string $type
*/
public function __construct(
string $code,
int $quantity,
float $unitPrice,
?string $description,
string $type = self::TYPE_COMPONENT
) {
$this->code = $code;
$this->description = $description;
$this->quantity = $quantity;
$this->setUnitPrice($unitPrice);
$this->type = $type;
}
/**
* @param ComponentInventoryLogEntry $logEntry
*/
public function addLogEntry(ComponentInventoryLogEntry $logEntry): void
{
if (null === $this->logEntries) {
$this->logEntries = new ArrayCollection();
}
$this->logEntries->add($logEntry);
}
/**
* @param int $currentQuantity
* @param int $increaseWithQuantity
* @param float $currentUnitPrice
* @param float $updatedUnitPrice
* @return float
*/
public static function calculateUnitPrice(
int $currentQuantity,
int $increaseWithQuantity,
float $currentUnitPrice,
float $updatedUnitPrice
): float {
$updatedQuantity = $currentQuantity + $increaseWithQuantity;
return ($currentQuantity * $currentUnitPrice + $increaseWithQuantity * $updatedUnitPrice) / $updatedQuantity;
}
/**
* @return string
*/
public function getCode(): string
{
return $this->code;
}
/**
* @return string|null
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection<ComponentInventoryLogEntry>
*/
public function getLogEntries(): Collection
{
return $this->logEntries;
}
/**
* @return int
*/
public function getQuantity(): int
{
return $this->quantity;
}
/**
* @return float
*/
public function getTotalValue(): float
{
return $this->quantity * $this->getUnitPrice();
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @return string[]
*/
public static function getTypeChoices(): array
{
return [
self::TYPE_COMPONENT,
self::TYPE_SALES_ITEM,
];
}
/**
* @return float
*/
public function getUnitPrice(): float
{
return (float) $this->unitPrice;
}
/**
* @param string $code
*/
public function setCode(string $code): void
{
$this->code = $code;
}
/**
* @param string|null $description
*/
public function setDescription(?string $description): void
{
$this->description = $description;
}
/**
* @param int $quantity
*/
public function setQuantity(int $quantity): void
{
$this->quantity = $quantity;
}
/**
* @param string $type
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* @param float $unitPrice
*/
public function setUnitPrice(float $unitPrice): void
{
$this->unitPrice = number_format($unitPrice, 3, '.', '');
}
}