<?php
namespace App\Entity;
use App\Exception\CurrencyException;
use App\Exception\InvalidArgumentException;
use App\Model\Country;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Exception;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* @ORM\Entity(
* repositoryClass="App\Repository\InvoiceRepository"
* )
* @ORM\Table(
* name="invoice",
* options={"collate"="utf8_swedish_ci"},
* uniqueConstraints={
* @ORM\UniqueConstraint(
* name="invoice_order_number",
* columns={"entity","order_number"}
* )
* }
* )
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(
* name="entity",
* type="string",
* length=50
* )
* @ORM\DiscriminatorMap({
* "invoice"="Invoice",
* "credit"="CreditInvoice",
* "proforma"="ProformaInvoice",
* "down_payment"="DownPaymentInvoice"
* })
* @ORM\HasLifecycleCallbacks
*/
abstract class AbstractInvoice implements EntityInterface, LoggableInterface, SalesDocumentInterface, SalesDocumentDiscountInterface
{
use DocumentTrait;
use LoggableTrait;
use SalesItemListTrait;
use VatJustificationTrait;
const STATUS_DRAFT = 'draft';
const STATUS_INVOICED = 'invoiced';
/**
* @ORM\Id
* @ORM\Column(
* type="integer"
* )
* @ORM\GeneratedValue(
* strategy="AUTO"
* )
*
* @var int|null
*/
protected ?int $id = null;
/**
* @ORM\OneToOne(
* targetEntity="CompanyDocumentAddress",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinColumn(
* name="buyer_id"
* )
*
* @Assert\Valid
*
* @var CompanyDocumentAddress|null
*/
protected ?CompanyDocumentAddress $buyer = null;
/**
* @ORM\Column(
* name="commodity_code",
* type="string",
* length=50,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $commodityCode = null;
/**
* @ORM\Column(
* name="confirmation_of_exit",
* type="boolean",
* nullable=true
* )
*
* @var bool|null
*/
protected ?bool $confirmationOfExit = null;
/**
* @ORM\Column(
* name="confirmation_of_exit_set",
* type="boolean"
* )
*
* @var bool
*/
protected bool $confirmationOfExitSet = false;
/**
* This is used when CoE is set in a draft invoice, because not set and value NULL must be handled separately.
*
* @var string|null
*/
protected ?string $confirmationOfExitTemp = null;
/**
* @ORM\OneToOne(
* targetEntity="CompanyDocumentAddress",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinColumn(
* name="consignee_id"
* )
*
* @Assert\Valid
*
* @var CompanyDocumentAddress|null
*/
protected ?CompanyDocumentAddress $consignee = null;
/**
* @ORM\Column(
* name="customs_data_per_item",
* type="boolean"
* )
*
* @var bool
*/
protected bool $customsDataPerItem = false;
/**
* @ORM\Column(
* name="country_of_origin",
* type="string",
* length=100,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $countryOfOrigin = 'EC - Finland';
/**
* @ORM\OneToOne(
* targetEntity="CompanyDocumentAddress",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinColumn(
* name="delivery_address_id"
* )
*
* @Assert\Valid
*
* @var CompanyDocumentAddress|null
*/
protected ?CompanyDocumentAddress $deliveryAddress = null;
/**
* @ORM\Column(
* name="delivery_date",
* type="date",
* nullable=true
* )
*
* @var DateTime|null
*/
protected ?DateTime $deliveryDate = null;
/**
* @ORM\Column(
* name="description_of_goods",
* type="string",
* length=1000,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $descriptionOfGoods = null;
/**
* @ORM\OneToMany(
* targetEntity="DocumentVersionInvoice",
* mappedBy="invoice",
* cascade={"persist","remove"}
* )
* @ORM\OrderBy({"created" = "DESC"})
*
* @var Collection<DocumentVersionInvoice>
*/
protected Collection $documentVersions;
/**
* @ORM\Column(
* type="json",
* nullable=true
* )
*
* @var array|null
*/
protected ?array $electronicInvoiceResponse = null;
/**
* @ORM\Column(
* name="final_destination",
* type="string",
* length=5,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $finalDestination = null;
/**
* @ORM\OneToOne(
* targetEntity="CompanyDocumentAddress",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinColumn(
* name="invoicing_address_id"
* )
*
* @Assert\Valid
*
* @var CompanyDocumentAddress|null
*/
protected ?CompanyDocumentAddress $invoicingAddress = null;
/**
* @ORM\ManyToMany(
* targetEntity="LogEntry",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinTable(
* name="invoice_log_entry",
* joinColumns={
* @ORM\JoinColumn(
* name="invoice_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
* },
* inverseJoinColumns={
* @ORM\JoinColumn(
* name="log_entry_id",
* referencedColumnName="id",
* unique=true,
* onDelete="cascade"
* )
* }
* )
* @ORM\OrderBy({"time" = "ASC"})
*
* @Assert\Valid
*
* @var Collection<LogEntry>
*/
protected $logEntries;
/**
* @ORM\Column(
* name="marks_and_numbers",
* type="string",
* length=100,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $marksAndNumbers = null;
/**
* @ORM\Column(
* type="string",
* length=1,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $modeOfTransport = null;
/**
* @ORM\Column(
* type="string",
* length=2,
* nullable=true
* )
* @Assert\Choice(
* callback="getNatureOfTransactionChoices"
* )
*
* @var string|null
*/
protected ?string $natureOfTransaction = null;
/**
* @ORM\Column(
* type="string",
* length=5000,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $notes = null;
/**
* @ORM\Column(
* name="order_number",
* type="integer",
* nullable=true
* )
*
* @var int|null
*/
protected ?int $orderNumber = null;
/**
* @ORM\Column(
* name="place_of_loading",
* type="string",
* length=200,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $placeOfLoading = null;
/**
* @ORM\ManyToOne(
* targetEntity="SalesCase",
* inversedBy="invoices"
* )
* @ORM\JoinColumn(
* name="sales_case_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
*
* @Assert\NotNull
*
* @var SalesCase
*/
protected SalesCase $salesCase;
/**
* @ORM\ManyToMany(
* targetEntity="SalesItem",
* cascade={"persist","remove"},
* orphanRemoval=true,
* fetch="EXTRA_LAZY"
* )
* @ORM\JoinTable(
* name="invoice_sales_item",
* joinColumns={
* @ORM\JoinColumn(
* name="invoice_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
* },
* inverseJoinColumns={
* @ORM\JoinColumn(
* name="sales_item_id",
* referencedColumnName="id",
* unique=true,
* onDelete="cascade"
* )
* }
* )
* @ORM\OrderBy({"position" = "ASC"})
*
* @Assert\Valid
*
* @var Collection<SalesItem>
*/
protected $salesItems;
/**
* @var bool
*/
protected bool $salesItemsPopulated = false;
/**
* @ORM\Column(
* name="terms_of_delivery",
* type="string",
* length=500,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $termsOfDelivery = null;
/**
* @ORM\ManyToMany(
* targetEntity="TermsOfPaymentRow",
* cascade={"persist","remove"},
* orphanRemoval=true
* )
* @ORM\JoinTable(
* name="invoice_terms_of_payment_row",
* joinColumns={
* @ORM\JoinColumn(
* name="invoice_id",
* referencedColumnName="id",
* onDelete="cascade"
* )
* },
* inverseJoinColumns={
* @ORM\JoinColumn(
* name="terms_of_payment_row_id",
* referencedColumnName="id",
* unique=true,
* onDelete="cascade"
* )
* }
* )
*
* @Assert\Valid
*
* @var Collection<TermsOfPaymentRow>
*/
protected $termsOfPaymentRows;
/**
* @ORM\Column(
* type="string",
* length=2000,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $text = null;
/**
* @ORM\Column(
* name="total_volume",
* type="string",
* length=100,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $totalVolume = null;
/**
* @ORM\Column(
* name="total_weight_gross",
* type="integer",
* nullable=true
* )
* @Assert\Range(
* min=0
* )
*
* @var int|null
*/
protected ?int $totalWeightGross = null;
/**
* @ORM\Column(
* name="total_weight_net",
* type="integer",
* nullable=true
* )
* @Assert\Range(
* min=0
* )
*
* @var int|null
*/
protected ?int $totalWeightNet = null;
/**
* @ORM\Column(
* type="string",
* length=500,
* nullable=true
* )
*
* @var string|null
*/
protected ?string $transportation = null;
/**
* @param SalesCase $salesCase
*/
public function __construct(SalesCase $salesCase)
{
$this->salesCase = $salesCase;
$this->documentVersions = new ArrayCollection();
$this->logEntries = new ArrayCollection();
$this->salesItems = new ArrayCollection();
$this->termsOfPaymentRows = new ArrayCollection();
}
/**
* @param DocumentVersionInvoice $documentVersion
*
* @throws InvalidArgumentException
*/
public function addDocumentVersion(DocumentVersionInvoice $documentVersion)
{
if ($documentVersion->getInvoice() !== $this) {
throw new InvalidArgumentException('Document version has mismatching invoice document.');
}
$this->documentVersions->add($documentVersion);
}
/**
* @param TermsOfPaymentRow $row
*/
public function addTermsOfPaymentRow(TermsOfPaymentRow $row): void
{
if ($this->termsOfPaymentRows === null) {
$this->termsOfPaymentRows = new ArrayCollection();
}
$this->termsOfPaymentRows->add($row);
}
/**
* @return CompanyDocumentAddress|null
*/
public function getBuyer(): ?CompanyDocumentAddress
{
return $this->buyer;
}
/**
* @return string|null
*/
public function getCommodityCode(): ?string
{
return $this->commodityCode;
}
/**
* @return bool|null
*/
public function getConfirmationOfExit(): ?bool
{
return $this->confirmationOfExit;
}
/**
* @return string|null
*/
public function getConfirmationOfExitTemp(): ?string
{
if ($this->confirmationOfExitSet) {
if ($this->confirmationOfExit === false) {
return 'waiting';
} elseif ($this->confirmationOfExit === true) {
return 'received';
} else {
return 'not_required';
}
}
return null;
}
/**
* @return CompanyDocumentAddress|null
*/
public function getConsignee(): ?CompanyDocumentAddress
{
return $this->consignee;
}
/**
* @return null|string
*/
public function getCountryOfOrigin(): ?string
{
return $this->countryOfOrigin;
}
/**
* @return CompanyDocumentAddress|null
*/
public function getDeliveryAddress(): ?CompanyDocumentAddress
{
return $this->deliveryAddress;
}
/**
* @return DateTime|null
*/
public function getDeliveryDate(): ?DateTime
{
return $this->deliveryDate;
}
/**
* @return null|string
*/
public function getDescriptionOfGoods(): ?string
{
return $this->descriptionOfGoods;
}
/**
* @return DocumentVersionInvoice|null
*/
public function getDocumentVersion(): ?DocumentVersionInvoice
{
if ($this->documentVersions->count() > 0) {
return $this->documentVersions->first();
}
return null;
}
/**
* @return ArrayCollection|DocumentVersionInvoice[]
*/
public function getDocumentVersions()
{
return $this->documentVersions;
}
/**
* @return DateTime|null
*
* @throws Exception
*/
public function getDueDate(): ?DateTime
{
if (count($this->getTermsOfPaymentRows()) > 0) {
/* @var TermsOfPaymentRow $first */
$first = $this->termsOfPaymentRows->first();
if (null !== $dueDate = $first->getDueDate()) {
return $dueDate;
}
if (null !== $days = $first->getDays()) {
if (null !== $deliveryDate = $this->getDeliveryDate()) {
$dueDate = clone $deliveryDate;
$dueDate->add(new \DateInterval('P' . $days . 'D'));
return $dueDate;
}
}
}
return null;
}
/**
* @return DateTime|null
*
* @throws Exception
*/
public function getDueDateAfterDelivery(): ?DateTime
{
if (null !== $deliveryDate = $this->getDeliveryDate()) {
if (count($this->getTermsOfPaymentRows()) > 0) {
/* @var TermsOfPaymentRow $first */
$first = $this->termsOfPaymentRows->first();
if (null !== $days = $first->getDays()) {
$dueDate = clone $deliveryDate;
$dueDate->add(new \DateInterval('P' . $days . 'D'));
return $dueDate;
}
}
}
return null;
}
/**
* @return string|null
*/
public function getElectronicInvoiceId(): ?string
{
if (null !== $response = $this->electronicInvoiceResponse) {
return $response['id'];
}
return null;
}
/**
* @return array|null
*/
public function getElectronicInvoiceResponse(): ?array
{
return $this->electronicInvoiceResponse;
}
/**
* @return DateTime|null
*
* @throws Exception
*/
public function getElectronicInvoiceSent(): ?DateTime
{
if (null !== $response = $this->electronicInvoiceResponse) {
return new DateTime($response['created_at']);
}
return null;
}
/**
* @return string|null
*/
public function getElectronicInvoiceStatus(): ?string
{
if (null !== $response = $this->electronicInvoiceResponse) {
return $response['status'];
}
return null;
}
/**
* @return null|string
*/
public function getFinalDestination(): ?string
{
return $this->finalDestination;
}
/**
* @return string|null
*/
public function getFinalDestinationName(): ?string
{
if ($this->finalDestination !== null) {
$country = new Country($this->finalDestination);
return $country->getName();
}
return null;
}
/**
* @return float
*
* @throws CurrencyException
* @throws Exception
*/
public function getGrossMargin(): float
{
$purchasePrices = [];
foreach ($this->salesCase->getPurchaseOrders() as $purchaseOrder) {
if ($purchaseOrder->isSent()) {
foreach ($purchaseOrder->getSalesItems() as $salesItem) {
if (null !== $purchasePrice = $salesItem->getPurchasePrice()) {
$purchasePrices[$salesItem->getCode()] = $purchasePrice;
}
}
}
}
$totalCostOfSales = 0;
$noPurchasePrice = [];
foreach ($this->salesItems as $salesItem) {
if (array_key_exists($salesItem->getCode(), $purchasePrices)) {
$totalCostOfSales += $purchasePrices[$salesItem->getCode()] * $salesItem->getQuantity();
} else {
$noPurchasePrice[] = $salesItem->getPositionDisplay();
}
}
if (count($noPurchasePrice) > 0) {
throw new Exception('No purchase price could be found in POs for positions ' . implode(', ', $noPurchasePrice) . '.');
}
if (($totalSales = $this->getValueNet()) <= 0) {
throw new Exception('The OC has no total sales value.');
}
return ($totalSales - $totalCostOfSales) / $totalSales;
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return CompanyDocumentAddress|null
*/
public function getInvoicingAddress(): ?CompanyDocumentAddress
{
return $this->invoicingAddress;
}
/**
* @return null|string
*/
public function getMarksAndNumbers(): ?string
{
return $this->marksAndNumbers;
}
/**
* @return null|string
*/
public function getModeOfTransport(): ?string
{
return $this->modeOfTransport;
}
/**
* @return string[]
*/
public static function getModeOfTransportChoices(): array
{
return [
'1', '2', '3', '4', '5', '7', '8', '9',
];
}
/**
* @return string|null
*/
public function getNatureOfTransaction(): ?string
{
return $this->natureOfTransaction;
}
/**
* @return string[]
*/
public static function getNatureOfTransactionChoices(): array
{
return [
'11', '12',
'21', '22', '23',
'31', '32', '33', '34',
'41', '42',
'51', '52',
'60',
'71', '72',
'80',
'91', '99',
];
}
/**
* @return null|string
*/
public function getNotes(): ?string
{
return $this->notes;
}
/**
* @param string $numberPrefix
* @param int $orderNumberPrefix
*
* @return string
*/
protected function getNumberParent(string $numberPrefix, int $orderNumberPrefix): string
{
return $numberPrefix . str_pad($this->salesCase->getId(), 6, '0', STR_PAD_LEFT)
. '-'
. ($this->isDraft() ? 'DRAFT' : $orderNumberPrefix . str_pad($this->getOrderNumber(), 5, '0', STR_PAD_LEFT));
}
/**
* @return int|null
*/
public function getOrderNumber(): ?int
{
return $this->orderNumber;
}
/**
* @return int
*/
public function getOrderNumberWithType(): int
{
list(,$orderNumber) = explode('-', $this->getNumber());
return (int) $orderNumber;
}
/**
* @return null|string
*/
public function getPlaceOfLoading(): ?string
{
return $this->placeOfLoading;
}
/**
* @return string
*/
public function getPreviewFileName(): string
{
$type = 'Invoice';
if ($this instanceof CreditInvoice) {
$type = 'Credit Invoice';
} elseif ($this instanceof ProformaInvoice) {
$type = 'Proforma Invoice';
} elseif ($this instanceof DownPaymentInvoice) {
$type = 'Down Payment Invoice';
}
return $type . ' - ' . $this->getNumber() . ' - Preview ' . date('Y-m-d') . '.pdf';
}
/**
* @return string|null
*/
public function getReferenceNumber(): ?string
{
if ($this->isDraft()) {
return null;
}
list(,$orderNumber) = explode('-', $this->getNumber());
$number = (string) $orderNumber;
$j = 0;
$sum = 0;
$weight = [7, 3, 1];
for ($i = strlen($number); $i > 0; $i--) {
$sum += $number[$i - 1] * $weight[$j++ % 3];
}
return $number . ((10 - ($sum % 10)) % 10);
}
/**
* @return SalesCase
*/
public function getSalesCase(): SalesCase
{
return $this->salesCase;
}
/**
* @return Collection<SalesItem>
*/
public function getSalesItems(): Collection
{
if (!$this->salesItemsPopulated) {
$currency = $this->getCurrency();
foreach ($this->salesItems as $salesItem) {
$salesItem->setCurrency($currency);
$salesItem->setCurrencyExchangeRate($this->currencyExchangeRate);
}
$this->salesItemsPopulated = true;
}
return $this->salesItems;
}
/**
* @return array
*/
public static function getStatusChoices(): array
{
return [
self::STATUS_DRAFT,
self::STATUS_INVOICED,
];
}
/**
* @return null|string
*/
public function getTermsOfDelivery(): ?string
{
return $this->termsOfDelivery;
}
/**
* @return ArrayCollection|TermsOfPaymentRow[]
*/
public function getTermsOfPaymentRows()
{
return $this->termsOfPaymentRows;
}
/**
* @return null|string
*/
public function getText(): ?string
{
return $this->text;
}
/**
* @return null|string
*/
public function getTotalVolume(): ?string
{
return $this->totalVolume;
}
/**
* @return null|int
*/
public function getTotalWeightGross(): ?int
{
return $this->totalWeightGross;
}
/**
* @return null|int
*/
public function getTotalWeightNet(): ?int
{
return $this->totalWeightNet;
}
/**
* @return null|string
*/
public function getTransportation(): ?string
{
return $this->transportation;
}
/**
* @return string
*/
abstract public function getType(): string;
/**
* @return bool
*/
public function isCurrencyExchangeRateLocked(): bool
{
return !in_array(
$this->status,
[
self::STATUS_DRAFT,
]
);
}
/**
* @return bool
*/
public function isCustomsDataPerItem(): bool
{
return $this->customsDataPerItem;
}
/**
* @return bool
*/
public function isDraft(): bool
{
return $this->getStatus() == self::STATUS_DRAFT;
}
/**
* @return bool
*/
public function isElectronicInvoiceStatusPending(): bool
{
if (null !== $response = $this->electronicInvoiceResponse) {
return $response['status'] == 'PENDING';
}
return false;
}
/**
* @return bool
*/
public function isElectronicInvoicingPossible(): bool
{
if (!(($this instanceof Invoice) || ($this instanceof DownPaymentInvoice) || ($this instanceof CreditInvoice))) {
return false;
}
if (!$this->isInvoiced()) {
return false;
}
if (null === $this->salesCase->getCompany()->getElectronicInvoicingIdentifier()) {
return false;
}
return true;
}
/**
* @return bool
*/
public function isElectronicInvoiceSent(): bool
{
return (null !== $this->electronicInvoiceResponse);
}
/**
* @return bool
*/
public function isInvoiced(): bool
{
return $this->getStatus() == self::STATUS_INVOICED;
}
/**
* @param TermsOfPaymentRow $row
*/
public function removeTermsOfPaymentRow(TermsOfPaymentRow $row)
{
if (null !== $this->termsOfPaymentRows) {
$this->termsOfPaymentRows->removeElement($row);
}
}
/**
* @param CompanyDocumentAddress|null $buyer
*/
public function setBuyer(?CompanyDocumentAddress $buyer)
{
$this->buyer = $buyer;
}
/**
* @param string|null $commodityCode
*/
public function setCommodityCode(?string $commodityCode)
{
$this->commodityCode = $commodityCode;
}
/**
* @param bool|null $confirmationOfExit
*/
public function setConfirmationOfExit(?bool $confirmationOfExit)
{
$this->confirmationOfExit = $confirmationOfExit;
}
/**
* @param string|null $confirmationOfExitTemp
*/
public function setConfirmationOfExitTemp(?string $confirmationOfExitTemp)
{
$this->confirmationOfExitTemp = $confirmationOfExitTemp;
$this->confirmationOfExitSet = true;
switch ($confirmationOfExitTemp) {
case 'not_required':
$this->setConfirmationOfExit(null);
break;
case 'waiting':
$this->setConfirmationOfExit(false);
break;
}
}
/**
* @param CompanyDocumentAddress|null $consignee
*/
public function setConsignee(?CompanyDocumentAddress $consignee)
{
$this->consignee = $consignee;
}
/**
* @param string|null $countryOfOrigin
*/
public function setCountryOfOrigin(?string $countryOfOrigin)
{
$this->countryOfOrigin = $countryOfOrigin;
}
/**
* @param bool $customsDataPerItem
*/
public function setCustomsDataPerItem(bool $customsDataPerItem)
{
$this->customsDataPerItem = $customsDataPerItem;
}
/**
* @param CompanyDocumentAddress|null $deliveryAddress
*/
public function setDeliveryAddress(?CompanyDocumentAddress $deliveryAddress)
{
$this->deliveryAddress = $deliveryAddress;
}
/**
* @param DateTime|null $deliveryDate
*/
public function setDeliveryDate(?DateTime $deliveryDate)
{
$this->deliveryDate = $deliveryDate;
}
/**
* @param string|null $descriptionOfGoods
*/
public function setDescriptionOfGoods(?string $descriptionOfGoods)
{
$this->descriptionOfGoods = $descriptionOfGoods;
}
/**
* @param array|null $electronicInvoiceResponse
*/
public function setElectronicInvoiceResponse(?array $electronicInvoiceResponse): void
{
$this->electronicInvoiceResponse = $electronicInvoiceResponse;
}
/**
* @param string|null $finalDestination
*/
public function setFinalDestination(?string $finalDestination)
{
$this->finalDestination = $finalDestination;
}
/**
* @param CompanyDocumentAddress|null $invoicingAddress
*/
public function setInvoicingAddress(?CompanyDocumentAddress $invoicingAddress)
{
$this->invoicingAddress = $invoicingAddress;
}
/**
* @param string|null $marksAndNumbers
*/
public function setMarksAndNumbers(?string $marksAndNumbers)
{
$this->marksAndNumbers = $marksAndNumbers;
}
/**
* @param string|null $modeOfTransport
*/
public function setModeOfTransport(?string $modeOfTransport): void
{
$this->modeOfTransport = $modeOfTransport;
}
/**
* @param string|null $natureOfTransaction
*/
public function setNatureOfTransaction(?string $natureOfTransaction): void
{
$this->natureOfTransaction = $natureOfTransaction;
}
/**
* @param string|null $notes
*/
public function setNotes(?string $notes)
{
$this->notes = $notes;
}
/**
* @param int|null $orderNumber
*/
public function setOrderNumber(?int $orderNumber)
{
$this->orderNumber = $orderNumber;
}
/**
* @param string|null $placeOfLoading
*/
public function setPlaceOfLoading(?string $placeOfLoading)
{
$this->placeOfLoading = $placeOfLoading;
}
/**
* @param string|null $totalVolume
*/
public function setTotalVolume(?string $totalVolume)
{
$this->totalVolume = $totalVolume;
}
/**
* @param int|null $totalWeightGross
*/
public function setTotalWeightGross(?int $totalWeightGross)
{
$this->totalWeightGross = $totalWeightGross;
}
/**
* @param int|null $totalWeightNet
*/
public function setTotalWeightNet(?int $totalWeightNet)
{
$this->totalWeightNet = $totalWeightNet;
}
/**
* @param string|null $termsOfDelivery
*/
public function setTermsOfDelivery(?string $termsOfDelivery)
{
$this->termsOfDelivery = $termsOfDelivery;
}
/**
* @param string|null $text
*/
public function setText(?string $text)
{
$this->text = $text;
}
/**
* @param string|null $transportation
*/
public function setTransportation(?string $transportation)
{
$this->transportation = $transportation;
}
/**
* @Assert\Callback
*
* @param ExecutionContextInterface $context
*
* @throws Exception
*/
public function validateDeliveryDate(ExecutionContextInterface $context)
{
/**
* If days have been defined in any of the terms of payment rows
* then delivery date must be defined in the invoice.
*/
if (null === $this->deliveryDate) {
foreach ($this->termsOfPaymentRows as $termsOfPaymentRow) {
if (null !== $termsOfPaymentRow->getDays()) {
$context->buildViolation('validation.deliveryDate.required')
->setTranslationDomain('Invoice')
->atPath('deliveryDate')
->addViolation();
}
}
}
/**
* Validate the due date.
*/
if (null === $this->getDueDate()) {
$context->buildViolation('validation.dueDate.required')
->setTranslationDomain('Invoice')
->addViolation();
}
}
/**
* @Assert\Callback
*
* @param ExecutionContextInterface $context
*/
public function validateVatJustification(ExecutionContextInterface $context)
{
if ($this->vat == 0 && $this->vatJustification === null) {
$context->buildViolation('validation.vatJustification.not_selected')
->setTranslationDomain('Invoice')
->atPath('vatJustification')
->addViolation();
}
}
}