vendor/bluue/sales-bundle/src/Entity/Invoice.php line 53

Open in your IDE?
  1. <?php
  2. /**
  3.  * @author Quentin CHATELAIN (contact@scaledev.fr)
  4.  * @copyright 2021 - ScaleDEV SAS, 12 RUE CHARLES MORET, 10120 ST ANDRE LES VERGERS
  5.  * @license commercial
  6.  */
  7. declare(strict_types=1);
  8. namespace Bluue\SalesBundle\Entity;
  9. use App\Entity\Traits\EntityManagerServiceEntity;
  10. use App\Services\SoftdeleteFilter;
  11. use Bluue\SalesBundle\DoctrineExtensions\EditPricesWithTaxEntity;
  12. use DateTime;
  13. use App\Entity\User;
  14. use DateTimeInterface;
  15. use App\Entity\Context;
  16. use App\Entity\Currency;
  17. use Doctrine\ORM\NonUniqueResultException;
  18. use Symfony\Component\Uid\Uuid;
  19. use Doctrine\ORM\Mapping as ORM;
  20. use Gedmo\Mapping\Annotation as Gedmo;
  21. use Doctrine\Common\Collections\Criteria;
  22. use Bluue\CustomersBundle\Entity\Customer;
  23. use Doctrine\Common\Collections\Collection;
  24. use Doctrine\Common\Collections\ArrayCollection;
  25. use Bluue\SalesBundle\Repository\InvoiceRepository;
  26. use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
  27. use App\DoctrineExtensions\Cancelable\Traits\UserCancelableEntity;
  28. use App\DoctrineExtensions\Validatable\Traits\UserValidatableEntity;
  29. use App\DoctrineExtensions\Timestampable\Traits\UserTimestampableEntity;
  30. use App\DoctrineExtensions\SoftDeleteable\Traits\UserSoftDeleteableEntity;
  31. use App\Entity\Establishment;
  32. /**
  33.  * @ORM\Entity(repositoryClass=InvoiceRepository::class)
  34.  * @ORM\Table(name="sales_bundle__invoice", indexes={
  35.  *  @ORM\Index(name="internal_name", columns={"internal_name"}),
  36.  *  @ORM\Index(name="reference", columns={"reference"}),
  37.  *  @ORM\Index(name="total_amount_untaxed", columns={"total_amount_untaxed"}),
  38.  *  @ORM\Index(name="total_amount", columns={"total_amount"}),
  39.  *  @ORM\Index(name="residual", columns={"residual"}),
  40.  *  @ORM\Index(name="validated_at", columns={"validated_at"}),
  41.  *  @ORM\Index(name="canceled_at", columns={"canceled_at"}),
  42.  *  @ORM\Index(name="deleted_at", columns={"deleted_at"}),
  43.  *  @ORM\Index(name="created_at", columns={"created_at"}),
  44.  *  @ORM\Index(name="updated_at", columns={"updated_at"})
  45.  * })
  46.  * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
  47.  */
  48. class Invoice
  49. {
  50.     use UserValidatableEntity;
  51.     use UserCancelableEntity;
  52.     use UserTimestampableEntity;
  53.     use UserSoftDeleteableEntity;
  54.     use EditPricesWithTaxEntity;
  55.     use EntityManagerServiceEntity;
  56.     /**
  57.      * @ORM\Id
  58.      * @ORM\Column(type="uuid")
  59.      * @ORM\GeneratedValue(strategy="CUSTOM")
  60.      * @ORM\CustomIdGenerator(class=UuidGenerator::class)
  61.      */
  62.     private ?Uuid $id null;
  63.     /**
  64.      * @ORM\ManyToOne(targetEntity=Context::class)
  65.      */
  66.     private ?Context $context null;
  67.     /**
  68.      * @ORM\ManyToOne(targetEntity=Customer::class)
  69.      * @ORM\JoinColumn(nullable=false)
  70.      */
  71.     private ?Customer $customer null;
  72.     /**
  73.      * @ORM\ManyToOne(targetEntity=User::class)
  74.      */
  75.     private ?User $commercial null;
  76.     /**
  77.      * @ORM\ManyToOne(targetEntity=Customer::class)
  78.      */
  79.     private ?Customer $invoice_address null;
  80.     /**
  81.      * @ORM\ManyToOne(targetEntity=Customer::class)
  82.      */
  83.     private ?Customer $delivery_address null;
  84.     /**
  85.      * @ORM\ManyToOne(targetEntity=Customer::class)
  86.      */
  87.     private ?Customer $invoiceContact null;
  88.     /**
  89.      * @ORM\ManyToOne(targetEntity=Customer::class)
  90.      */
  91.     private ?Customer $deliveryContact null;
  92.     /**
  93.      * @ORM\ManyToOne(targetEntity=Quotation::class, inversedBy="invoices")
  94.      */
  95.     private ?Quotation $quotation null;
  96.     /**
  97.      * @ORM\ManyToOne(targetEntity=Order::class, inversedBy="invoices")
  98.      */
  99.     private ?Order $order null;
  100.     /**
  101.      * @ORM\ManyToOne(targetEntity=CreditNote::class, inversedBy="invoices")
  102.      */
  103.     private ?CreditNote $credit_note null;
  104.     /**
  105.      * @ORM\ManyToOne(targetEntity=Currency::class)
  106.      */
  107.     private ?Currency $currency null;
  108.     /**
  109.      * @ORM\ManyToOne(targetEntity=PaymentTerm::class)
  110.      */
  111.     private ?PaymentTerm $payment_term null;
  112.     /**
  113.      * @ORM\Column(type="decimal", precision=20, scale=12)
  114.      */
  115.     private ?string $currency_change_rate null;
  116.     /**
  117.      * @ORM\ManyToOne(targetEntity=PaymentMethod::class)
  118.      */
  119.     private ?PaymentMethod $payment_method null;
  120.     /**
  121.      * @ORM\Column(type="string", length=128, nullable="true")
  122.      */
  123.     private ?string $reference null;
  124.     /**
  125.      * @ORM\Column(type="string", length=255, nullable="true")
  126.      */
  127.     private ?string $internal_name null;
  128.     /**
  129.      * @ORM\Column(type="string", length=255, nullable="true")
  130.      */
  131.     private ?string $external_name null;
  132.     /**
  133.      * @ORM\Column(type="boolean")
  134.      */
  135.     private bool $reduced_vat false;
  136.     /**
  137.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  138.      */
  139.     private ?string $total_discount_untaxed null;
  140.     /**
  141.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  142.      */
  143.     private ?string $totalDiscount null;
  144.     /**
  145.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  146.      */
  147.     private ?string $total_amount_no_discount_untaxed null;
  148.     /**
  149.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  150.      */
  151.     private ?string $totalAmountNoDiscount null;
  152.     /**
  153.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  154.      */
  155.     private ?string $total_amount_untaxed null;
  156.     /**
  157.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  158.      */
  159.     private ?string $total_tax_amount null;
  160.     /**
  161.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  162.      */
  163.     private ?string $total_amount null;
  164.     /**
  165.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  166.      */
  167.     private ?string $residual null;
  168.     /**
  169.      * @ORM\Column(type="date", nullable="true")
  170.      */
  171.     private ?DateTimeInterface $due_date null;
  172.     /**
  173.      * @ORM\Column(type="boolean")
  174.      */
  175.     private bool $is_deposit false;
  176.     /**
  177.      * @ORM\Column(type="json")
  178.      */
  179.     private array $options = [];
  180.     /**
  181.      * @ORM\OneToMany(
  182.      *      targetEntity=InvoiceLine::class,
  183.      *      mappedBy="invoice",
  184.      *      cascade={"persist", "remove"},
  185.      *      fetch="EXTRA_LAZY"
  186.      * )
  187.      * @ORM\OrderBy({"position" = "ASC"})
  188.      */
  189.     private Collection $lines;
  190.     /**
  191.      * @ORM\OneToMany(targetEntity=DocumentPayment::class, mappedBy="invoice", fetch="EXTRA_LAZY")
  192.      */
  193.     private Collection $payments;
  194.     /**
  195.      * @ORM\OneToMany(targetEntity=DeliveryNote::class, mappedBy="invoice")
  196.      */
  197.     private Collection $delivery_notes;
  198.     /**
  199.      * @ORM\OneToMany(targetEntity=CreditNote::class, mappedBy="invoice")
  200.      */
  201.     private Collection $creditNotes;
  202.     /**
  203.      * @var mixed $recurringInvoice
  204.      */
  205.     private $recurringInvoice;
  206.     /**
  207.      * @ORM\ManyToOne(targetEntity=Establishment::class)
  208.      */
  209.     private ?Establishment $establishment null;
  210.     public function __construct()
  211.     {
  212.         $this->lines = new ArrayCollection();
  213.         $this->payments = new ArrayCollection();
  214.         $this->delivery_notes = new ArrayCollection();
  215.         $this->creditNotes = new ArrayCollection();
  216.     }
  217.     /**
  218.      * @return Uuid|null
  219.      */
  220.     public function getId(): ?Uuid
  221.     {
  222.         return $this->id;
  223.     }
  224.     /**
  225.      * @return Invoice
  226.      */
  227.     public function setId(): self
  228.     {
  229.         $this->id null;
  230.         return $this;
  231.     }
  232.     /**
  233.      * @return Context|null
  234.      */
  235.     public function getContext(): ?Context
  236.     {
  237.         return $this->context;
  238.     }
  239.     /**
  240.      * @param Context|null $context
  241.      * @return Invoice
  242.      */
  243.     public function setContext(?Context $context): self
  244.     {
  245.         $this->context $context;
  246.         return $this;
  247.     }
  248.     /**
  249.      * @return Customer|null
  250.      * @throws NonUniqueResultException
  251.      */
  252.     public function getCustomer(): ?Customer
  253.     {
  254.         if ($this->em && $this->customer) {
  255.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  256.             $customer $this->em->getRepository(Customer::class)
  257.                 ->createQueryBuilder('c')
  258.                 ->where('c.id = :customerId')
  259.                 ->setParameter('customerId'$this->customer->getId()->toBinary())
  260.                 ->getQuery()
  261.                 ->getOneOrNullResult();
  262.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  263.             return $customer;
  264.         }
  265.         return $this->customer;
  266.     }
  267.     /**
  268.      * @param Customer $customer
  269.      * @return Invoice
  270.      */
  271.     public function setCustomer(Customer $customer): self
  272.     {
  273.         if ($this->customer && $this->customer->getId() !== $customer->getId()) {
  274.             $this->setInvoiceContact(null)->setDeliveryContact(null);
  275.         }
  276.         $this->customer $customer;
  277.         $this->setDeliveryAddress(null);
  278.         return $this->setInvoiceAddress($customer);
  279.     }
  280.     /**
  281.      * @return User|null
  282.      * @throws NonUniqueResultException
  283.      */
  284.     public function getCommercial(): ?User
  285.     {
  286.         if ($this->em && $this->commercial) {
  287.             SoftdeleteFilter::disable($this->em, [User::class]);
  288.             $commercial $this->em->getRepository(User::class)
  289.                 ->createQueryBuilder('u')
  290.                 ->where('u.id = :commercialId')
  291.                 ->setParameter('commercialId'$this->commercial->getId()->toBinary())
  292.                 ->getQuery()
  293.                 ->getOneOrNullResult();
  294.             SoftdeleteFilter::enable($this->em, [User::class]);
  295.             return $commercial;
  296.         }
  297.         return $this->commercial;
  298.     }
  299.     /**
  300.      * @param User|null $commercial
  301.      * @return Invoice
  302.      */
  303.     public function setCommercial(?User $commercial): self
  304.     {
  305.         $this->commercial $commercial;
  306.         return $this;
  307.     }
  308.     /**
  309.      * @return Customer|null
  310.      * @throws NonUniqueResultException
  311.      */
  312.     public function getInvoiceAddress(): ?Customer
  313.     {
  314.         if ($this->em && $this->invoice_address) {
  315.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  316.             $invoiceAddress $this->em->getRepository(Customer::class)
  317.                 ->createQueryBuilder('c')
  318.                 ->where('c.id = :invoiceAddressId')
  319.                 ->setParameter('invoiceAddressId'$this->invoice_address->getId()->toBinary())
  320.                 ->getQuery()
  321.                 ->getOneOrNullResult();
  322.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  323.             return $invoiceAddress;
  324.         }
  325.         return $this->invoice_address;
  326.     }
  327.     /**
  328.      * @param Customer|null $invoice_address
  329.      * @return Invoice
  330.      */
  331.     public function setInvoiceAddress(?Customer $invoice_address): self
  332.     {
  333.         $this->invoice_address $invoice_address;
  334.         return $this;
  335.     }
  336.     /**
  337.      * @return Customer|null
  338.      * @throws NonUniqueResultException
  339.      */
  340.     public function getDeliveryAddress(): ?Customer
  341.     {
  342.         if ($this->em && $this->delivery_address) {
  343.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  344.             $deliveryAddress $this->em->getRepository(Customer::class)
  345.                 ->createQueryBuilder('c')
  346.                 ->where('c.id = :deliveryAddressId')
  347.                 ->setParameter('deliveryAddressId'$this->delivery_address->getId()->toBinary())
  348.                 ->getQuery()
  349.                 ->getOneOrNullResult();
  350.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  351.             return $deliveryAddress;
  352.         }
  353.         return $this->delivery_address;
  354.     }
  355.     /**
  356.      * @param Customer|null $delivery_address
  357.      * @return Invoice
  358.      */
  359.     public function setDeliveryAddress(?Customer $delivery_address): self
  360.     {
  361.         $this->delivery_address $delivery_address;
  362.         return $this;
  363.     }
  364.     /**
  365.      * @return Customer|null
  366.      * @throws NonUniqueResultException
  367.      */
  368.     public function getInvoiceContact(): ?Customer
  369.     {
  370.         if ($this->em && $this->invoiceContact) {
  371.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  372.             $invoiceContact $this->em->getRepository(Customer::class)
  373.                 ->createQueryBuilder('c')
  374.                 ->where('c.id = :invoiceContactId')
  375.                 ->setParameter('invoiceContactId'$this->invoiceContact->getId()->toBinary())
  376.                 ->getQuery()
  377.                 ->getOneOrNullResult();
  378.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  379.             return $invoiceContact;
  380.         }
  381.         return $this->invoiceContact;
  382.     }
  383.     /**
  384.      * @param Customer|null $invoiceContact
  385.      * @return Invoice
  386.      */
  387.     public function setInvoiceContact(?Customer $invoiceContact): Invoice
  388.     {
  389.         $this->invoiceContact $invoiceContact;
  390.         return $this;
  391.     }
  392.     /**
  393.      * @return Customer|null
  394.      * @throws NonUniqueResultException
  395.      */
  396.     public function getDeliveryContact(): ?Customer
  397.     {
  398.         if ($this->em && $this->deliveryContact) {
  399.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  400.             $deliveryContact $this->em->getRepository(Customer::class)
  401.                 ->createQueryBuilder('c')
  402.                 ->where('c.id = :deliveryContactId')
  403.                 ->setParameter('deliveryContactId'$this->deliveryContact->getId()->toBinary())
  404.                 ->getQuery()
  405.                 ->getOneOrNullResult();
  406.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  407.             return $deliveryContact;
  408.         }
  409.         return $this->deliveryContact;
  410.     }
  411.     /**
  412.      * @param Customer|null $deliveryContact
  413.      * @return Invoice
  414.      */
  415.     public function setDeliveryContact(?Customer $deliveryContact): Invoice
  416.     {
  417.         $this->deliveryContact $deliveryContact;
  418.         return $this;
  419.     }
  420.     /**
  421.      * @return Quotation|null
  422.      * @throws NonUniqueResultException
  423.      */
  424.     public function getQuotation(): ?Quotation
  425.     {
  426.         if ($this->em && $this->quotation) {
  427.             SoftdeleteFilter::disable($this->em, [Quotation::class]);
  428.             $quotation $this->em->getRepository(Quotation::class)
  429.                 ->createQueryBuilder('q')
  430.                 ->where('q.id = :quotationId')
  431.                 ->setParameter('quotationId'$this->quotation->getId()->toBinary())
  432.                 ->getQuery()
  433.                 ->getOneOrNullResult();
  434.             SoftdeleteFilter::enable($this->em, [Quotation::class]);
  435.             return $quotation;
  436.         }
  437.         return $this->quotation;
  438.     }
  439.     /**
  440.      * @param Quotation|null $quotation
  441.      * @return Invoice
  442.      * @throws NonUniqueResultException
  443.      */
  444.     public function setQuotation(?Quotation $quotation): self
  445.     {
  446.         $this->quotation $quotation;
  447.         if ($quotation) {
  448.             $this->setCustomer($quotation->getCustomer());
  449.             $this->setCommercial($quotation->getCommercial());
  450.             $this->setInvoiceAddress($quotation->getInvoiceAddress());
  451.             $this->setDeliveryAddress($quotation->getDeliveryAddress());
  452.             $this->setInvoiceContact($quotation->getInvoiceContact());
  453.             $this->setDeliveryContact($quotation->getDeliveryContact());
  454.             $this->setCurrency($quotation->getCurrency());
  455.             $this->setContext($quotation->getContext());
  456.             $this->setEstablishment($quotation->getEstablishment());
  457.             $this->setExternalName($quotation->getExternalName());
  458.             if (!$this->getIsDeposit()) {
  459.                 $this->setTotalAmountNoDiscountUntaxed($quotation->getTotalAmountNoDiscountUntaxed());
  460.                 $this->setTotalAmountNoDiscount($quotation->getTotalAmountNoDiscount());
  461.                 $this->setTotalDiscountUntaxed($quotation->getTotalDiscountUntaxed());
  462.                 $this->setTotalDiscount($quotation->getTotalDiscount());
  463.                 $this->setTotalTaxAmount($quotation->getTotalTaxAmount());
  464.                 $this->setTotalAmountUntaxed($quotation->getTotalAmountUntaxed());
  465.                 $this->setTotalAmount($quotation->getTotalAmount());
  466.             }
  467.             if (!empty($quotation->getOptions()['note'])) {
  468.                 $this->addOptions([
  469.                     'note' => $quotation->getOptions()['note']
  470.                 ]);
  471.             }
  472.             if (!empty($quotation->getOptions()['customerNote'])) {
  473.                 $this->addOptions([
  474.                     'customerNote' => $quotation->getOptions()['customerNote']
  475.                 ]);
  476.             }
  477.         }
  478.         return $this;
  479.     }
  480.     /**
  481.      * @return Order|null
  482.      */
  483.     public function getOrder(): ?Order
  484.     {
  485.         return $this->order;
  486.     }
  487.     /**
  488.      * @return array
  489.      * @throws NonUniqueResultException
  490.      */
  491.     public function getOrders(): array
  492.     {
  493.         if ($order $this->getOrder()) {
  494.             return [$order];
  495.         } else {
  496.             $orders = [];
  497.             foreach ($this->getDeliveryNotes() as $deliveryNote) {
  498.                 $order $deliveryNote->getOrder();
  499.                 if ($order && !in_array($order$orders)) {
  500.                     $orders[] = $order;
  501.                 }
  502.             }
  503.             return $orders;
  504.         }
  505.     }
  506.     /**
  507.      * @param Order|null $order
  508.      * @return Invoice
  509.      * @throws NonUniqueResultException
  510.      */
  511.     public function setOrder(?Order $order): self
  512.     {
  513.         $this->order $order;
  514.         if ($order && !$this->quotation) {
  515.             $this->setCustomer($order->getCustomer());
  516.             $this->setCommercial($order->getCommercial());
  517.             $this->setInvoiceAddress($order->getInvoiceAddress());
  518.             $this->setDeliveryAddress($order->getDeliveryAddress());
  519.             $this->setInvoiceContact($order->getInvoiceContact());
  520.             $this->setDeliveryContact($order->getDeliveryContact());
  521.             $this->setCurrency($order->getCurrency());
  522.             $this->setContext($order->getContext());
  523.             $this->setEstablishment($order->getEstablishment());
  524.             $this->setExternalName($order->getExternalName());
  525.             if (!$this->getIsDeposit()) {
  526.                 $this->setTotalAmountNoDiscountUntaxed($order->getTotalAmountNoDiscountUntaxed());
  527.                 $this->setTotalAmountNoDiscount($order->getTotalAmountNoDiscount());
  528.                 $this->setTotalDiscountUntaxed($order->getTotalDiscountUntaxed());
  529.                 $this->setTotalDiscount($order->getTotalDiscount());
  530.                 $this->setTotalTaxAmount($order->getTotalTaxAmount());
  531.                 $this->setTotalAmountUntaxed($order->getTotalAmountUntaxed());
  532.                 $this->setTotalAmount($order->getTotalAmount());
  533.             }
  534.             if (!empty($order->getOptions()['note'])) {
  535.                 $this->addOptions([
  536.                     'note' => $order->getOptions()['note']
  537.                 ]);
  538.             }
  539.             if (!empty($order->getOptions()['customerNote'])) {
  540.                 $this->addOptions([
  541.                     'customerNote' => $order->getOptions()['customerNote']
  542.                 ]);
  543.             }
  544.         }
  545.         return $this;
  546.     }
  547.     /**
  548.      * @return CreditNote|null
  549.      */
  550.     public function getCreditNote(): ?CreditNote
  551.     {
  552.         return $this->credit_note;
  553.     }
  554.     /**
  555.      * @param CreditNote|null $credit_note
  556.      * @param bool|null $onlyCreditNote
  557.      * @return Invoice
  558.      * @throws NonUniqueResultException
  559.      */
  560.     public function setCreditNote(?CreditNote $credit_note, ?bool $onlyCreditNote false): self
  561.     {
  562.         $this->credit_note $credit_note;
  563.         if ($credit_note && !$onlyCreditNote) {
  564.             $this->setCustomer($credit_note->getCustomer());
  565.             $this->setCommercial($credit_note->getCommercial());
  566.             $this->setInvoiceAddress($credit_note->getInvoiceAddress());
  567.             $this->setDeliveryAddress($credit_note->getDeliveryAddress());
  568.             $this->setInvoiceContact($credit_note->getInvoiceContact());
  569.             $this->setDeliveryContact($credit_note->getDeliveryContact());
  570.             $this->setTotalAmountUntaxed($credit_note->getResidual());
  571.             $this->setTotalAmount($credit_note->getResidual());
  572.             $this->setCurrency($credit_note->getCurrency());
  573.             $this->setContext($credit_note->getContext());
  574.             $this->setEstablishment($credit_note->getEstablishment());
  575.             $this->setExternalName($credit_note->getExternalName());
  576.             if (!empty($credit_note->getOptions()['note'])) {
  577.                 $this->addOptions([
  578.                     'note' => $credit_note->getOptions()['note']
  579.                 ]);
  580.             }
  581.             if (!empty($credit_note->getOptions()['customerNote'])) {
  582.                 $this->addOptions([
  583.                     'customerNote' => $credit_note->getOptions()['customerNote']
  584.                 ]);
  585.             }
  586.         }
  587.         return $this;
  588.     }
  589.     /**
  590.      * @return Currency|null
  591.      */
  592.     public function getCurrency(): ?Currency
  593.     {
  594.         return $this->currency;
  595.     }
  596.     /**
  597.      * @param Currency $currency
  598.      * @return Invoice
  599.      */
  600.     public function setCurrency(Currency $currency): self
  601.     {
  602.         $this->currency $currency;
  603.         return $this->setCurrencyChangeRate($currency->getChangeRate());
  604.     }
  605.     /**
  606.      * @return PaymentTerm|null
  607.      */
  608.     public function getPaymentTerm(): ?PaymentTerm
  609.     {
  610.         return $this->payment_term;
  611.     }
  612.     /**
  613.      * @param PaymentTerm|null $payment_term
  614.      * @return Invoice
  615.      */
  616.     public function setPaymentTerm(?PaymentTerm $payment_term): self
  617.     {
  618.         $this->payment_term $payment_term;
  619.         return $this;
  620.     }
  621.     /**
  622.      * @return string|null
  623.      */
  624.     public function getCurrencyChangeRate(): ?string
  625.     {
  626.         return $this->currency_change_rate;
  627.     }
  628.     /**
  629.      * @param string|null $currency_change_rate
  630.      * @return Invoice
  631.      */
  632.     public function setCurrencyChangeRate(?string $currency_change_rate): self
  633.     {
  634.         $this->currency_change_rate $currency_change_rate;
  635.         return $this;
  636.     }
  637.     /**
  638.      * @return PaymentMethod|null
  639.      * @throws NonUniqueResultException
  640.      */
  641.     public function getPaymentMethod(): ?PaymentMethod
  642.     {
  643.         if ($this->em && $this->payment_method) {
  644.             SoftdeleteFilter::disable($this->em, [PaymentMethod::class]);
  645.             $payment_method $this->em->getRepository(PaymentMethod::class)
  646.                 ->createQueryBuilder('pm')
  647.                 ->where('pm.id = :paymentMethodId')
  648.                 ->setParameter('paymentMethodId'$this->payment_method->getId()->toBinary())
  649.                 ->getQuery()
  650.                 ->getOneOrNullResult();
  651.             SoftdeleteFilter::enable($this->em, [PaymentMethod::class]);
  652.             return $payment_method;
  653.         }
  654.         return $this->payment_method;
  655.     }
  656.     /**
  657.      * @param PaymentMethod|null $payment_method
  658.      */
  659.     public function setPaymentMethod(?PaymentMethod $payment_method): void
  660.     {
  661.         $this->payment_method $payment_method;
  662.     }
  663.     /**
  664.      * @return string|null
  665.      */
  666.     public function getReference(): ?string
  667.     {
  668.         return $this->reference;
  669.     }
  670.     /**
  671.      * @param string|null $reference
  672.      * @return Invoice
  673.      */
  674.     public function setReference(?string $reference): self
  675.     {
  676.         $this->reference $reference;
  677.         return $this;
  678.     }
  679.     /**
  680.      * @return string|null
  681.      */
  682.     public function getInternalName(): ?string
  683.     {
  684.         return $this->internal_name;
  685.     }
  686.     /**
  687.      * @param string|null $internal_name
  688.      * @return Invoice
  689.      */
  690.     public function setInternalName(?string $internal_name): self
  691.     {
  692.         $this->internal_name $internal_name;
  693.         return $this;
  694.     }
  695.     /**
  696.      * @return string|null
  697.      */
  698.     public function getExternalName(): ?string
  699.     {
  700.         return $this->external_name;
  701.     }
  702.     /**
  703.      * @param string|null $external_name
  704.      * @return Invoice
  705.      */
  706.     public function setExternalName(?string $external_name): self
  707.     {
  708.         $this->external_name $external_name;
  709.         return $this;
  710.     }
  711.     /**
  712.      * @return bool
  713.      */
  714.     public function isReducedVat(): bool
  715.     {
  716.         return $this->reduced_vat;
  717.     }
  718.     /**
  719.      * @param bool $reduced_vat
  720.      * @return Invoice
  721.      */
  722.     public function setReducedVat(bool $reduced_vat): self
  723.     {
  724.         $this->reduced_vat $reduced_vat;
  725.         return $this;
  726.     }
  727.     /**
  728.      * @return string|null
  729.      */
  730.     public function getTotalDiscountUntaxed(): ?string
  731.     {
  732.         return $this->total_discount_untaxed;
  733.     }
  734.     /**
  735.      * @param string|null $total_discount_untaxed
  736.      * @return Invoice
  737.      */
  738.     public function setTotalDiscountUntaxed(?string $total_discount_untaxed): self
  739.     {
  740.         $this->total_discount_untaxed $total_discount_untaxed;
  741.         return $this;
  742.     }
  743.     /**
  744.      * @return string|null
  745.      */
  746.     public function getTotalDiscount(): ?string
  747.     {
  748.         return $this->totalDiscount;
  749.     }
  750.     /**
  751.      * @param string|null $totalDiscount
  752.      * @return Invoice
  753.      */
  754.     public function setTotalDiscount(?string $totalDiscount): Invoice
  755.     {
  756.         $this->totalDiscount $totalDiscount;
  757.         return $this;
  758.     }
  759.     /**
  760.      * @return string|null
  761.      */
  762.     public function getTotalAmountNoDiscountUntaxed(): ?string
  763.     {
  764.         return $this->total_amount_no_discount_untaxed;
  765.     }
  766.     /**
  767.      * @param string|null $total_amount_no_discount_untaxed
  768.      * @return Invoice
  769.      */
  770.     public function setTotalAmountNoDiscountUntaxed(?string $total_amount_no_discount_untaxed): self
  771.     {
  772.         $this->total_amount_no_discount_untaxed $total_amount_no_discount_untaxed;
  773.         return $this;
  774.     }
  775.     /**
  776.      * @return string|null
  777.      */
  778.     public function getTotalAmountNoDiscount(): ?string
  779.     {
  780.         return $this->totalAmountNoDiscount;
  781.     }
  782.     /**
  783.      * @param string|null $totalAmountNoDiscount
  784.      * @return Invoice
  785.      */
  786.     public function setTotalAmountNoDiscount(?string $totalAmountNoDiscount): Invoice
  787.     {
  788.         $this->totalAmountNoDiscount $totalAmountNoDiscount;
  789.         return $this;
  790.     }
  791.     /**
  792.      * @return string|null
  793.      */
  794.     public function getTotalAmountUntaxed(): ?string
  795.     {
  796.         return $this->total_amount_untaxed;
  797.     }
  798.     /**
  799.      * @param string|null $total_amount_untaxed
  800.      * @return Invoice
  801.      */
  802.     public function setTotalAmountUntaxed(?string $total_amount_untaxed): self
  803.     {
  804.         $this->total_amount_untaxed $total_amount_untaxed;
  805.         return $this;
  806.     }
  807.     /**
  808.      * @return string|null
  809.      */
  810.     public function getTotalTaxAmount(): ?string
  811.     {
  812.         return $this->total_tax_amount;
  813.     }
  814.     /**
  815.      * @param string|null $total_tax_amount
  816.      * @return Invoice
  817.      */
  818.     public function setTotalTaxAmount(?string $total_tax_amount): self
  819.     {
  820.         $this->total_tax_amount $total_tax_amount;
  821.         return $this;
  822.     }
  823.     /**
  824.      * @return string|null
  825.      */
  826.     public function getTotalAmount(): ?string
  827.     {
  828.         return $this->total_amount;
  829.     }
  830.     /**
  831.      * @param string|null $total_amount
  832.      * @return Invoice
  833.      */
  834.     public function setTotalAmount(?string $total_amount): self
  835.     {
  836.         $this->total_amount $total_amount;
  837.         return $this;
  838.     }
  839.     /**
  840.      * @return string|null
  841.      */
  842.     public function getResidual(): ?string
  843.     {
  844.         return $this->residual;
  845.     }
  846.     /**
  847.      * @param string|null $residual
  848.      * @return Invoice
  849.      */
  850.     public function setResidual(?string $residual): self
  851.     {
  852.         $this->residual $residual;
  853.         return $this;
  854.     }
  855.     /**
  856.      * @return DateTimeInterface|null
  857.      */
  858.     public function getDueDate(): ?DateTimeInterface
  859.     {
  860.         return $this->due_date;
  861.     }
  862.     /**
  863.      * @param mixed $due_date
  864.      * @return Invoice
  865.      */
  866.     public function setDueDate($due_date): self
  867.     {
  868.         if ($due_date instanceof DateTimeInterface) {
  869.             $this->due_date $due_date;
  870.         } elseif ($due_date) {
  871.             $this->due_date = new DateTime($due_date);
  872.         } else {
  873.             $this->due_date null;
  874.         }
  875.         return $this;
  876.     }
  877.     /**
  878.      * @return bool
  879.      */
  880.     public function getIsDeposit(): bool
  881.     {
  882.         return $this->is_deposit;
  883.     }
  884.     /**
  885.      * @param bool $is_deposit
  886.      * @return Invoice
  887.      */
  888.     public function setIsDeposit(bool $is_deposit): self
  889.     {
  890.         $this->is_deposit $is_deposit;
  891.         return $this;
  892.     }
  893.     /**
  894.      * @return array
  895.      */
  896.     public function getOptions(): array
  897.     {
  898.         return $this->options;
  899.     }
  900.     /**
  901.      * @param array $options
  902.      * @return Invoice
  903.      */
  904.     public function setOptions(array $options): self
  905.     {
  906.         $this->options $options;
  907.         return $this;
  908.     }
  909.     /**
  910.      * @param array $options
  911.      * @return Invoice
  912.      */
  913.     public function addOptions(array $options): self
  914.     {
  915.         return $this->setOptions(array_merge($this->options$options));
  916.     }
  917.     /**
  918.      * @return Collection|InvoiceLine[]
  919.      */
  920.     public function getLines(): Collection
  921.     {
  922.         return $this->getFilterLines();
  923.     }
  924.     /**
  925.      * @param InvoiceLine $line
  926.      * @return $this
  927.      */
  928.     public function addLine(InvoiceLine $line): self
  929.     {
  930.         if (!$this->lines->contains($line)) {
  931.             $this->lines[] = $line;
  932.             if ($line->getInvoice() !== $this) {
  933.                 $line->setInvoice($this);
  934.             }
  935.         }
  936.         return $this;
  937.     }
  938.     /**
  939.      * @param InvoiceLine $line
  940.      * @return $this
  941.      */
  942.     public function removeLine(InvoiceLine $line): self
  943.     {
  944.         $this->lines->removeElement($line);
  945.         return $this;
  946.     }
  947.     /**
  948.      * @param bool $withGroups
  949.      * @param bool $all
  950.      * @param bool $withPacks
  951.      * @return Collection|InvoiceLine[]
  952.      */
  953.     public function getFilterLines(bool $withGroups truebool $all falsebool $withPacks true): Collection
  954.     {
  955.         if ($all) {
  956.             $lines $this->lines;
  957.             $goodLines = [];
  958.             foreach ($lines as $line) {
  959.                 if (!$line->getParent() && !$line->getPackParent()) {
  960.                     $goodLines[] = $line;
  961.                     foreach ($line->getChildrens() as $child) {
  962.                         $goodLines[] = $child;
  963.                         foreach ($child->getPackChildrens() as $grandChild) {
  964.                             $goodLines[] = $grandChild;
  965.                         }
  966.                     }
  967.                     foreach ($line->getPackChildrens() as $child) {
  968.                         $goodLines[] = $child;
  969.                     }
  970.                 }
  971.             }
  972.             return new ArrayCollection($goodLines);
  973.         }
  974.         $criteria Criteria::create();
  975.         if ($withGroups) {
  976.             $criteria
  977.                 ->where(Criteria::expr()->eq('parent'null))
  978.                 ->andWhere(Criteria::expr()->eq('packParent'null));
  979.         } else {
  980.             if ($withPacks) {
  981.                 $criteria->andWhere(Criteria::expr()->eq('is_pack'true));
  982.             } else {
  983.                 $criteria->andWhere(Criteria::expr()->eq('is_pack'false));
  984.             }
  985.             $criteria->where(Criteria::expr()->eq('is_group'false));
  986.         }
  987.         return $this->lines->matching($criteria);
  988.     }
  989.     /**
  990.      * @return Collection|DocumentPayment[]
  991.      */
  992.     public function getPayments(): Collection
  993.     {
  994.         return $this->payments;
  995.     }
  996.     /**
  997.      * @return Collection|DeliveryNote[]
  998.      */
  999.     public function getDeliveryNotes(): Collection
  1000.     {
  1001.         return $this->delivery_notes;
  1002.     }
  1003.     /**
  1004.      * @param DeliveryNote $deliveryNote
  1005.      * @return $this
  1006.      */
  1007.     public function addDeliveryNote(DeliveryNote $deliveryNote): self
  1008.     {
  1009.         if (!$this->delivery_notes->contains($deliveryNote)) {
  1010.             $this->delivery_notes[] = $deliveryNote;
  1011.             if ($deliveryNote->getInvoice() !== $this) {
  1012.                 $deliveryNote->setInvoice($this);
  1013.             }
  1014.         }
  1015.         return $this;
  1016.     }
  1017.     /**
  1018.      * @return bool
  1019.      */
  1020.     public function isCancelable(): bool
  1021.     {
  1022.         return !$this->getCanceledAt() && $this->getResidual() > && $this->getResidual() == $this->getTotalAmount();
  1023.     }
  1024.     /**
  1025.      * @return Invoice
  1026.      */
  1027.     public function duplicate(): Invoice
  1028.     {
  1029.         if ($this->id) {
  1030.             $clone = clone $this;
  1031.             $clone->setId();
  1032.             $clone->setCreatedAt(new DateTime());
  1033.             $clone->setCreatedBy(null);
  1034.             $clone->setUpdatedAt(new DateTime());
  1035.             $clone->setUpdatedBy(null);
  1036.             $clone->setValidatedAt(null);
  1037.             $clone->setValidatedBy(null);
  1038.             $clone->setCanceledAt(null);
  1039.             $clone->setCanceledBy(null);
  1040.             $clone->setContext(null);
  1041.             $clone->setEstablishment(null);
  1042.             $clone->setQuotation(null);
  1043.             $clone->setCreditNote(null);
  1044.             $clone->setReference(null);
  1045.             $clone->setResidual(null);
  1046.             $clone->setDueDate(null);
  1047.             $clone->addOptions([
  1048.                 'invoice_address' => null,
  1049.                 'delivery_address' => null
  1050.             ]);
  1051.             if (!$this->payment_method) {
  1052.                 $clone->setPaymentMethod(null);
  1053.             }
  1054.             if (!$this->payment_term) {
  1055.                 $clone->setPaymentTerm(null);
  1056.             }
  1057.             $clone->lines = new ArrayCollection();
  1058.             foreach ($this->getFilterLines() as $line) {
  1059.                 $clone_line $line->duplicate($clone);
  1060.                 $clone->addLine($clone_line);
  1061.             }
  1062.             return $clone;
  1063.         }
  1064.         return $this;
  1065.     }
  1066.     /**
  1067.      * @return mixed
  1068.      */
  1069.     public function getRecurringInvoice()
  1070.     {
  1071.         return $this->recurringInvoice;
  1072.     }
  1073.     /**
  1074.      * @param mixed $recurringInvoice
  1075.      * @return $this
  1076.      */
  1077.     public function setRecurringInvoice($recurringInvoice): self
  1078.     {
  1079.         $this->recurringInvoice $recurringInvoice;
  1080.         return $this;
  1081.     }
  1082.     /**
  1083.      * @return Establishment|null
  1084.      */
  1085.     public function getEstablishment(): ?Establishment
  1086.     {
  1087.         return $this->establishment;
  1088.     }
  1089.     /**
  1090.      * @param Establishment|null $establishment
  1091.      * @return $this
  1092.      */
  1093.     public function setEstablishment(?Establishment $establishment): self
  1094.     {
  1095.         $this->establishment $establishment;
  1096.         return $this;
  1097.     }
  1098.     /**
  1099.      * @return Collection
  1100.      */
  1101.     public function getCreditNotes(): Collection
  1102.     {
  1103.         return $this->creditNotes;
  1104.     }
  1105. }