<?php
/**
* @author Quentin CHATELAIN (contact@scaledev.fr)
* @copyright 2021 - ScaleDEV SAS, 12 RUE CHARLES MORET, 10120 ST ANDRE LES VERGERS
* @license commercial
*/
declare(strict_types=1);
namespace Bluue\SalesBundle\Entity;
use Bluue\SalesBundle\DoctrineExtensions\EditPricesWithTaxEntity;
use DateTime;
use App\Entity\User;
use App\Entity\Context;
use App\Entity\Currency;
use Symfony\Component\Uid\Uuid;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\Criteria;
use Bluue\CustomersBundle\Entity\Customer;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use App\Entity\Traits\ConfigurationServiceEntity;
use Bluue\SalesBundle\Repository\OrderRepository;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
use App\DoctrineExtensions\Validatable\Traits\UserValidatableEntity;
use App\DoctrineExtensions\Timestampable\Traits\UserTimestampableEntity;
use App\DoctrineExtensions\SoftDeleteable\Traits\UserSoftDeleteableEntity;
use App\Entity\Establishment;
/**
* @ORM\Entity(repositoryClass=OrderRepository::class)
* @ORM\Table(name="sales_bundle__order", indexes={
* @ORM\Index(name="internal_name", columns={"internal_name"}),
* @ORM\Index(name="reference", columns={"reference"}),
* @ORM\Index(name="total_amount_untaxed", columns={"total_amount_untaxed"}),
* @ORM\Index(name="total_amount", columns={"total_amount"}),
* @ORM\Index(name="residual", columns={"residual"}),
* @ORM\Index(name="deleted_at", columns={"deleted_at"}),
* @ORM\Index(name="created_at", columns={"created_at"}),
* @ORM\Index(name="updated_at", columns={"updated_at"})
* })
* @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
*/
class Order
{
use UserValidatableEntity;
use UserTimestampableEntity;
use UserSoftDeleteableEntity;
use ConfigurationServiceEntity;
use EditPricesWithTaxEntity;
/**
* @ORM\Id
* @ORM\Column(type="uuid")
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class=UuidGenerator::class)
*/
private ?Uuid $id = null;
/**
* @ORM\ManyToOne(targetEntity=Context::class)
*/
private ?Context $context = null;
/**
* @ORM\ManyToOne(targetEntity=Customer::class)
* @ORM\JoinColumn(nullable=false)
*/
private ?Customer $customer = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private ?User $commercial = null;
/**
* @ORM\ManyToOne(targetEntity=Customer::class)
*/
private ?Customer $invoice_address = null;
/**
* @ORM\ManyToOne(targetEntity=Customer::class)
*/
private ?Customer $delivery_address = null;
/**
* @ORM\ManyToOne(targetEntity=Customer::class)
*/
private ?Customer $invoiceContact = null;
/**
* @ORM\ManyToOne(targetEntity=Customer::class)
*/
private ?Customer $deliveryContact = null;
/**
* @ORM\ManyToOne(targetEntity=OrderState::class, fetch="EXTRA_LAZY")
*/
private ?OrderState $order_state = null;
/**
* @ORM\ManyToOne(targetEntity=Currency::class)
*/
private ?Currency $currency = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=12)
*/
private ?string $currency_change_rate = null;
/**
* @ORM\ManyToOne(targetEntity=PaymentMethod::class)
*/
private ?PaymentMethod $payment_method = null;
/**
* @ORM\Column(type="string", length=128, nullable="true")
*/
private ?string $reference = null;
/**
* @ORM\Column(type="string", length=255, nullable="true")
*/
private ?string $internal_name = null;
/**
* @ORM\Column(type="string", length=255, nullable="true")
*/
private ?string $external_name = null;
/**
* @ORM\Column(type="boolean")
*/
private bool $reduced_vat = false;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $total_discount_untaxed = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $totalDiscount = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $total_amount_no_discount_untaxed = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $totalAmountNoDiscount = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $total_amount_untaxed = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $total_tax_amount = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $total_amount = null;
/**
* @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
*/
private ?string $residual = null;
/**
* @ORM\Column(type="json")
*/
private array $options = [];
/**
* Virtual
* @var array
*/
private array $pdfOptions = [];
/**
* @ORM\OneToMany(
* targetEntity=OrderLine::class,
* mappedBy="order",
* cascade={"persist", "remove"},
* fetch="EXTRA_LAZY"
* )
* @ORM\OrderBy({"position" = "ASC"})
*/
private Collection $lines;
/**
* @ORM\OneToMany(targetEntity=OrderHistory::class, mappedBy="order", cascade={"persist"}, fetch="EXTRA_LAZY")
* @ORM\OrderBy({"id" = "DESC"})
*/
private Collection $histories;
/**
* @ORM\OneToMany(targetEntity=Invoice::class, mappedBy="order", cascade={"persist"}, fetch="EXTRA_LAZY")
*/
private Collection $invoices;
/**
* @ORM\OneToMany(targetEntity=DeliveryNote::class, mappedBy="order", cascade={"persist"}, fetch="EXTRA_LAZY")
*/
private Collection $delivery_notes;
/**
* @ORM\OneToMany(targetEntity=Quotation::class, mappedBy="order", fetch="EXTRA_LAZY")
*/
private Collection $quotations;
/**
* @ORM\ManyToOne(targetEntity=Establishment::class)
*/
private ?Establishment $establishment = null;
public function __construct()
{
$this->lines = new ArrayCollection();
$this->histories = new ArrayCollection();
$this->invoices = new ArrayCollection();
$this->delivery_notes = new ArrayCollection();
$this->quotations = new ArrayCollection();
}
/**
* @return Uuid|null
*/
public function getId(): ?Uuid
{
return $this->id;
}
/**
* @return Order
*/
public function setId(): self
{
$this->id = null;
return $this;
}
/**
* @return Context|null
*/
public function getContext(): ?Context
{
return $this->context;
}
/**
* @param Context|null $context
* @return Order
*/
public function setContext(?Context $context): self
{
$this->context = $context;
return $this;
}
/**
* @return Customer|null
*/
public function getCustomer(): ?Customer
{
return $this->customer;
}
/**
* @param Customer $customer
* @return Order
*/
public function setCustomer(Customer $customer): self
{
if ($this->customer && $this->customer->getId() !== $customer->getId()) {
$this->setInvoiceContact(null)->setDeliveryContact(null);
}
$this->customer = $customer;
$this->setDeliveryAddress(null);
return $this->setInvoiceAddress($customer);
}
/**
* @return User|null
*/
public function getCommercial(): ?User
{
return $this->commercial;
}
/**
* @param User|null $commercial
* @return $this
*/
public function setCommercial(?User $commercial): self
{
$this->commercial = $commercial;
return $this;
}
/**
* @return Customer|null
*/
public function getInvoiceAddress(): ?Customer
{
return $this->invoice_address;
}
/**
* @param Customer|null $invoice_address
* @return Order
*/
public function setInvoiceAddress(?Customer $invoice_address): self
{
$this->invoice_address = $invoice_address;
return $this;
}
/**
* @return Customer|null
*/
public function getDeliveryAddress(): ?Customer
{
return $this->delivery_address;
}
/**
* @param Customer|null $delivery_address
* @return Order
*/
public function setDeliveryAddress(?Customer $delivery_address): self
{
$this->delivery_address = $delivery_address;
return $this;
}
/**
* @return Customer|null
*/
public function getInvoiceContact(): ?Customer
{
return $this->invoiceContact;
}
/**
* @param Customer|null $invoiceContact
* @return Order
*/
public function setInvoiceContact(?Customer $invoiceContact): Order
{
$this->invoiceContact = $invoiceContact;
return $this;
}
/**
* @return Customer|null
*/
public function getDeliveryContact(): ?Customer
{
return $this->deliveryContact;
}
/**
* @param Customer|null $deliveryContact
* @return Order
*/
public function setDeliveryContact(?Customer $deliveryContact): Order
{
$this->deliveryContact = $deliveryContact;
return $this;
}
/**
* @return OrderState|null
*/
public function getOrderState(): ?OrderState
{
return $this->order_state;
}
/**
* @param OrderState|null $order_state
* @return Order
*/
public function setOrderState(?OrderState $order_state): self
{
$this->order_state = $order_state;
return $this;
}
/**
* @return Currency|null
*/
public function getCurrency(): ?Currency
{
return $this->currency;
}
/**
* @param Currency $currency
* @return Order
*/
public function setCurrency(Currency $currency): self
{
$this->currency = $currency;
return $this->setCurrencyChangeRate($currency->getChangeRate());
}
/**
* @return string|null
*/
public function getCurrencyChangeRate(): ?string
{
return $this->currency_change_rate;
}
/**
* @param string|null $currency_change_rate
* @return Order
*/
public function setCurrencyChangeRate(?string $currency_change_rate): self
{
$this->currency_change_rate = $currency_change_rate;
return $this;
}
/**
* @return PaymentMethod|null
*/
public function getPaymentMethod(): ?PaymentMethod
{
return $this->payment_method;
}
/**
* @param PaymentMethod|null $payment_method
* @return Order
*/
public function setPaymentMethod(?PaymentMethod $payment_method): Order
{
$this->payment_method = $payment_method;
return $this;
}
/**
* @return string|null
*/
public function getReference(): ?string
{
return $this->reference;
}
/**
* @param string|null $reference
* @return Order
*/
public function setReference(?string $reference): self
{
$this->reference = $reference;
return $this;
}
/**
* @return string|null
*/
public function getInternalName(): ?string
{
return $this->internal_name;
}
/**
* @param string|null $internal_name
* @return Order
*/
public function setInternalName(?string $internal_name): self
{
$this->internal_name = $internal_name;
return $this;
}
/**
* @return string|null
*/
public function getExternalName(): ?string
{
return $this->external_name;
}
/**
* @param string|null $external_name
* @return Order
*/
public function setExternalName(?string $external_name): self
{
$this->external_name = $external_name;
return $this;
}
/**
* @return bool
*/
public function isReducedVat(): bool
{
return $this->reduced_vat;
}
/**
* @param bool $reduced_vat
* @return Order
*/
public function setReducedVat(bool $reduced_vat): self
{
$this->reduced_vat = $reduced_vat;
return $this;
}
/**
* @return string|null
*/
public function getTotalDiscountUntaxed(): ?string
{
return $this->total_discount_untaxed;
}
/**
* @param string|null $total_discount_untaxed
* @return Order
*/
public function setTotalDiscountUntaxed(?string $total_discount_untaxed): self
{
$this->total_discount_untaxed = $total_discount_untaxed;
return $this;
}
/**
* @return string|null
*/
public function getTotalDiscount(): ?string
{
return $this->totalDiscount;
}
/**
* @param string|null $totalDiscount
* @return Order
*/
public function setTotalDiscount(?string $totalDiscount): Order
{
$this->totalDiscount = $totalDiscount;
return $this;
}
/**
* @return string|null
*/
public function getTotalAmountNoDiscountUntaxed(): ?string
{
return $this->total_amount_no_discount_untaxed;
}
/**
* @param string|null $total_amount_no_discount_untaxed
* @return Order
*/
public function setTotalAmountNoDiscountUntaxed(?string $total_amount_no_discount_untaxed): self
{
$this->total_amount_no_discount_untaxed = $total_amount_no_discount_untaxed;
return $this;
}
/**
* @return string|null
*/
public function getTotalAmountNoDiscount(): ?string
{
return $this->totalAmountNoDiscount;
}
/**
* @param string|null $totalAmountNoDiscount
* @return Order
*/
public function setTotalAmountNoDiscount(?string $totalAmountNoDiscount): Order
{
$this->totalAmountNoDiscount = $totalAmountNoDiscount;
return $this;
}
/**
* @return string|null
*/
public function getTotalAmountUntaxed(): ?string
{
return $this->total_amount_untaxed;
}
/**
* @param string|null $total_amount_untaxed
* @return Order
*/
public function setTotalAmountUntaxed(?string $total_amount_untaxed): self
{
$this->total_amount_untaxed = $total_amount_untaxed;
return $this;
}
/**
* @return string|null
*/
public function getTotalTaxAmount(): ?string
{
return $this->total_tax_amount;
}
/**
* @param string|null $total_tax_amount
* @return Order
*/
public function setTotalTaxAmount(?string $total_tax_amount): self
{
$this->total_tax_amount = $total_tax_amount;
return $this;
}
/**
* @return string|null
*/
public function getTotalAmount(): ?string
{
return $this->total_amount;
}
/**
* @param string|null $total_amount
* @return Order
*/
public function setTotalAmount(?string $total_amount): self
{
$this->total_amount = $total_amount;
return $this;
}
/**
* @return float|null
*/
public function getResidual(): ?float
{
return (float) $this->residual;
}
/**
* @param string|null $residual
* @return $this
*/
public function setResidual(?string $residual): self
{
$this->residual = $residual > $this->total_amount ? $this->total_amount : $residual;
return $this;
}
/**
* @return array
*/
public function getOptions(): array
{
return $this->options;
}
/**
* @param array $options
* @return Order
*/
public function setOptions(array $options): self
{
$this->options = $options;
return $this;
}
/**
* @param array $options
* @return Order
*/
public function addOptions(array $options): self
{
return $this->setOptions(array_merge($this->options, $options));
}
/**
* @return array
*/
public function getPdfOptions(): array
{
return $this->pdfOptions;
}
/**
* @param array $pdfOptions
* @return Order
*/
public function setPdfOptions(array $pdfOptions): Order
{
$this->pdfOptions = $pdfOptions;
return $this;
}
/**
* @return Collection|OrderLine[]
*/
public function getLines(): Collection
{
return $this->getFilterLines();
}
/**
* @param OrderLine $line
* @return $this
*/
public function addLine(OrderLine $line): self
{
if (!$this->lines->contains($line)) {
$this->lines[] = $line;
if ($line->getOrder() !== $this) {
$line->setOrder($this);
}
}
return $this;
}
/**
* @param OrderLine $line
* @return $this
*/
public function removeLine(OrderLine $line): self
{
$this->lines->removeElement($line);
return $this;
}
/**
* @param bool $withGroups
* @param bool $all
* @param bool $withPacks
* @return Collection|OrderLine[]
*/
public function getFilterLines(bool $withGroups = true, bool $all = false, bool $withPacks = true): Collection
{
if ($all) {
return $this->lines;
}
$criteria = Criteria::create();
if ($withGroups) {
$criteria
->where(Criteria::expr()->eq('parent', null))
->andWhere(Criteria::expr()->eq('packParent', null));
} else {
if ($withPacks) {
$criteria->andWhere(Criteria::expr()->eq('is_pack', true));
} else {
$criteria->andWhere(Criteria::expr()->eq('is_pack', false));
}
$criteria->where(Criteria::expr()->eq('is_group', false));
}
return $this->lines->matching($criteria);
}
/**
* @return Collection|OrderHistory[]
*/
public function getHistories(): Collection
{
return $this->histories;
}
/**
* @param Invoice $invoice
* @return $this
*/
public function addInvoice(Invoice $invoice): self
{
if (!$this->invoices->contains($invoice)) {
$this->invoices[] = $invoice;
if ($invoice->getOrder() !== $this) {
$invoice->setOrder($this);
}
}
return $this;
}
/**
* @return Collection|Invoice
*/
public function getInvoices(): Collection
{
$invoices = $this->invoices;
foreach ($this->getFilterDeliveryNotes(false, false, false, true) as $deliveryNoteValidated) {
$deliveryNoteInvoice = $deliveryNoteValidated->getInvoice();
if ($deliveryNoteInvoice && !$invoices->contains($deliveryNoteInvoice)) {
$invoices->add($deliveryNoteInvoice);
}
}
return $invoices;
}
/**
* @return Invoice|null
*/
public function getMainInvoice(): ?Invoice
{
$collection = $this->invoices->filter(function (Invoice $invoice) {
return !$invoice->getIsDeposit() && $invoice->getDeliveryNotes()->isEmpty() && !$invoice->isCanceled();
});
return $collection->count() ? $collection->first() : null;
}
/**
* @return Collection|Invoice[]
*/
public function getDepositInvoices(): Collection
{
return $this->invoices->filter(function (Invoice $invoice) {
return $invoice->getIsDeposit() && !$invoice->isCanceled();
});
}
/**
* @return Collection|Invoice[]
*/
public function getDeliveryNoteInvoices(): Collection
{
return $this->invoices->filter(function (Invoice $invoice) {
return !$invoice->getDeliveryNotes()->isEmpty() && !$invoice->isCanceled();
});
}
/**
* @return Collection|DeliveryNote[]
*/
public function getDeliveryNotes(): Collection
{
return $this->getFilterDeliveryNotes();
}
/**
* @param bool $all
* @param bool $draft
* @param bool $forInvoice
* @param bool $validated
* @return Collection|DeliveryNote
*/
public function getFilterDeliveryNotes(
bool $all = true,
bool $draft = true,
bool $forInvoice = false,
bool $validated = false
): Collection {
if ($all) {
return $this->delivery_notes;
}
$criteria = Criteria::create();
if ($draft) {
$criteria->where(Criteria::expr()->isNull('validatedAt'));
} elseif ($forInvoice) {
$criteria->where(Criteria::expr()->neq('validatedAt', null));
$criteria->andWhere(Criteria::expr()->isNull('invoice'));
$criteria->andWhere(Criteria::expr()->isNull('canceledAt'));
} elseif ($validated) {
$criteria->where(Criteria::expr()->neq('validatedAt', null));
$criteria->andWhere(Criteria::expr()->isNull('canceledAt'));
}
return $this->delivery_notes->matching($criteria);
}
/**
* @param bool $list
* @return Collection
*/
public function getRemainingLines(bool $list = true): Collection
{
$allLineTypes = $this->configService->get('sales_bundle__generation_of_delivery_note_with_all_line_types');
$withPack = $this->configService->get('sales_bundle__generation_of_delivery_note_with_pack');
$linesWithQtyZero = $this->configService->get('sales_bundle__order_remaining_lines_with_quantity_0');
$lines = $this->lines->filter(function (OrderLine $line) use ($withPack, $allLineTypes, $linesWithQtyZero) {
return ($line->getRemainingQuantity() > 0 || ($linesWithQtyZero && $line->getQuantity() == 0))
&& $line->getLineType()
&& (!$line->getIsPack() || $withPack)
&& ($allLineTypes || $line->getLineType()->getNumber() == 1);
});
if (!$list) {
return $lines;
}
return $lines->map(function (OrderLine $orderLine) {
return [
'id' => (string) $orderLine->getId(),
'quantity' => $orderLine->getRemainingQuantity()
];
});
}
/**
* @return bool
*/
public function isInvoicable(): bool
{
return $this->getValidatedAt()
&& $this->getDeliveryNoteInvoices()->isEmpty()
&& !$this->getMainInvoice();
}
/**
* @return bool
*/
public function isDeliveryNoteInvoicable(): bool
{
return $this->getValidatedAt()
&& $this->getResidual() > 0
&& $this->getDepositInvoices()->isEmpty()
&& !$this->getMainInvoice();
}
/**
* @return bool
*/
public function isDeliverable(): bool
{
return $this->getValidatedAt() && !$this->getRemainingLines()->isEmpty();
}
/**
* 0 => Pas prête
* 1 => Partiellement prête
* 2 => Prête
* @return int|null
*/
public function burstableStatus(): ?int
{
if (
$this->getOptions()
&& isset($this->getOptions()['shipments'])
&& isset($this->getOptions()['shipments']['status'])
) {
return $this->getOptions()['shipments']['status'];
} else {
return 0;
}
}
/**
* @return bool
*/
public function orderRemovedFromBurst(): bool
{
if (
$this->getOptions()
&& isset($this->getOptions()['shipments'])
&& isset($this->getOptions()['shipments']['orderRemovedFromBurst'])
) {
return $this->getOptions()['shipments']['orderRemovedFromBurst'];
} else {
return false;
}
}
/**
* @return float
*/
public function calcResidual(): float
{
$residual = (float) $this->getTotalAmount();
foreach ($this->getInvoices() as $invoice) {
if (!$invoice->isCanceled()) {
$residual -= $invoice->getTotalAmount();
}
}
return $residual;
}
/**
* @return float
*/
public function getAmountInvoicedUntaxed(): float
{
$amount = 0;
foreach ($this->getInvoices() as $invoice) {
if (!$invoice->isCanceled()) {
$amount += $invoice->getTotalAmountUntaxed();
}
}
return $amount;
}
/**
* @return Order
*/
public function duplicate(): Order
{
if ($this->id) {
$clone = clone $this;
$clone->setId();
$clone->setCreatedAt(new DateTime());
$clone->setCreatedBy(null);
$clone->setUpdatedAt(new DateTime());
$clone->setUpdatedBy(null);
$clone->setValidatedAt(null);
$clone->setValidatedBy(null);
$clone->setContext(null);
$clone->setEstablishment(null);
$clone->setOrderState(null);
$clone->setReference(null);
$clone->setResidual(null);
$clone->addOptions([
'invoice_address' => null,
'delivery_address' => null
]);
$clone->lines = new ArrayCollection();
foreach ($this->getFilterLines() as $line) {
$clone_line = $line->duplicate($clone);
$clone->addLine($clone_line);
}
return $clone;
}
return $this;
}
/**
* @return Customer|null
*/
public function getFinalDeliveryAddress(): ?Customer
{
return $this->getDeliveryAddress() ?: $this->getInvoiceAddress();
}
/**
* @return float
*/
public function getPercentage(): float
{
$residualPercentage = $this->getResidual() / (float) $this->getTotalAmount() * 100;
return round(100 - $residualPercentage, 2);
}
/**
* @return Collection
*/
public function getQuotations(): Collection
{
return $this->quotations;
}
/**
* @param Quotation $quotation
* @return $this
*/
public function addQuotation(Quotation $quotation): self
{
if (!$this->quotations->contains($quotation)) {
if ($this->getQuotations()->isEmpty()) {
$this->setCommercial($quotation->getCommercial());
$this->setCustomer($quotation->getCustomer());
$this->setInvoiceAddress($quotation->getInvoiceAddress());
$this->setDeliveryAddress($quotation->getDeliveryAddress());
$this->setInvoiceContact($quotation->getInvoiceContact());
$this->setDeliveryContact($quotation->getDeliveryContact());
$this->setCurrency($quotation->getCurrency());
$this->setContext($quotation->getContext());
$this->setEstablishment($quotation->getEstablishment());
$this->setExternalName($quotation->getExternalName());
$this->setTotalAmountNoDiscountUntaxed($quotation->getTotalAmountNoDiscountUntaxed());
$this->setTotalAmountNoDiscount($quotation->getTotalAmountNoDiscount());
$this->setTotalDiscount($quotation->getTotalDiscount());
$this->setTotalTaxAmount($quotation->getTotalTaxAmount());
$this->setTotalAmountUntaxed($quotation->getTotalAmountUntaxed());
$this->setTotalAmount($quotation->getTotalAmount());
if (!empty($quotation->getOptions()['note'])) {
$this->addOptions([
'note' => $quotation->getOptions()['note']
]);
}
if (!empty($quotation->getOptions()['customerNote'])) {
$this->addOptions([
'customerNote' => $quotation->getOptions()['customerNote']
]);
}
}
$this->quotations[] = $quotation;
}
return $this;
}
/**
* @return Quotation|null
*/
public function getQuotation(): ?Quotation
{
if ($this->quotations->isEmpty()) {
return null;
} else {
return $this->quotations->first();
}
}
/**
* @return Establishment|null
*/
public function getEstablishment(): ?Establishment
{
return $this->establishment;
}
/**
* @param Establishment $establishment
* @return $this
*/
public function setEstablishment(?Establishment $establishment): self
{
$this->establishment = $establishment;
return $this;
}
}