vendor/bluue/sales-bundle/src/Entity/CreditNote.php line 51

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 App\Entity\Context;
  15. use App\Entity\Currency;
  16. use Doctrine\ORM\NonUniqueResultException;
  17. use Symfony\Component\Uid\Uuid;
  18. use Doctrine\ORM\Mapping as ORM;
  19. use Gedmo\Mapping\Annotation as Gedmo;
  20. use Doctrine\Common\Collections\Criteria;
  21. use Bluue\CustomersBundle\Entity\Customer;
  22. use Doctrine\Common\Collections\Collection;
  23. use Doctrine\Common\Collections\ArrayCollection;
  24. use Bluue\SalesBundle\Repository\CreditNoteRepository;
  25. use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
  26. use App\DoctrineExtensions\Cancelable\Traits\UserCancelableEntity;
  27. use App\DoctrineExtensions\Validatable\Traits\UserValidatableEntity;
  28. use App\DoctrineExtensions\Timestampable\Traits\UserTimestampableEntity;
  29. use App\DoctrineExtensions\SoftDeleteable\Traits\UserSoftDeleteableEntity;
  30. use App\Entity\Establishment;
  31. /**
  32.  * @ORM\Entity(repositoryClass=CreditNoteRepository::class)
  33.  * @ORM\Table(name="sales_bundle__credit_note", indexes={
  34.  *  @ORM\Index(name="internal_name", columns={"internal_name"}),
  35.  *  @ORM\Index(name="reference", columns={"reference"}),
  36.  *  @ORM\Index(name="total_amount_untaxed", columns={"total_amount_untaxed"}),
  37.  *  @ORM\Index(name="total_amount", columns={"total_amount"}),
  38.  *  @ORM\Index(name="validated_at", columns={"validated_at"}),
  39.  *  @ORM\Index(name="canceled_at", columns={"canceled_at"}),
  40.  *  @ORM\Index(name="deleted_at", columns={"deleted_at"}),
  41.  *  @ORM\Index(name="created_at", columns={"created_at"}),
  42.  *  @ORM\Index(name="updated_at", columns={"updated_at"})
  43.  * })
  44.  * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
  45.  */
  46. class CreditNote
  47. {
  48.     use UserValidatableEntity;
  49.     use UserCancelableEntity;
  50.     use UserTimestampableEntity;
  51.     use UserSoftDeleteableEntity;
  52.     use EditPricesWithTaxEntity;
  53.     use EntityManagerServiceEntity;
  54.     /**
  55.      * @ORM\Id
  56.      * @ORM\Column(type="uuid")
  57.      * @ORM\GeneratedValue(strategy="CUSTOM")
  58.      * @ORM\CustomIdGenerator(class=UuidGenerator::class)
  59.      */
  60.     private ?Uuid $id null;
  61.     /**
  62.      * @ORM\ManyToOne(targetEntity=Context::class)
  63.      */
  64.     private ?Context $context null;
  65.     /**
  66.      * @ORM\ManyToOne(targetEntity=Customer::class)
  67.      * @ORM\JoinColumn(nullable=false)
  68.      */
  69.     private ?Customer $customer null;
  70.     /**
  71.      * @ORM\ManyToOne(targetEntity=User::class)
  72.      */
  73.     private ?User $commercial null;
  74.     /**
  75.      * @ORM\ManyToOne(targetEntity=Customer::class)
  76.      */
  77.     private ?Customer $invoice_address null;
  78.     /**
  79.      * @ORM\ManyToOne(targetEntity=Customer::class)
  80.      */
  81.     private ?Customer $delivery_address null;
  82.     /**
  83.      * @ORM\ManyToOne(targetEntity=Customer::class)
  84.      */
  85.     private ?Customer $invoiceContact null;
  86.     /**
  87.      * @ORM\ManyToOne(targetEntity=Customer::class)
  88.      */
  89.     private ?Customer $deliveryContact null;
  90.     /**
  91.      * @ORM\ManyToOne(targetEntity=Invoice::class, inversedBy="creditNotes")
  92.      */
  93.     private ?Invoice $invoice null;
  94.     /**
  95.      * @ORM\ManyToOne(targetEntity=Currency::class)
  96.      */
  97.     private ?Currency $currency null;
  98.     /**
  99.      * @ORM\Column(type="decimal", precision=20, scale=12)
  100.      */
  101.     private ?string $currency_change_rate null;
  102.     /**
  103.      * @ORM\ManyToOne(targetEntity=PaymentMethod::class)
  104.      */
  105.     private ?PaymentMethod $payment_method null;
  106.     /**
  107.      * @ORM\Column(type="string", length=128, nullable="true")
  108.      */
  109.     private ?string $reference null;
  110.     /**
  111.      * @ORM\Column(type="string", length=255, nullable="true")
  112.      */
  113.     private ?string $internal_name null;
  114.     /**
  115.      * @ORM\Column(type="string", length=255, nullable="true")
  116.      */
  117.     private ?string $external_name null;
  118.     /**
  119.      * @ORM\Column(type="boolean")
  120.      */
  121.     private bool $reduced_vat false;
  122.     /**
  123.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  124.      */
  125.     private ?string $total_amount_untaxed null;
  126.     /**
  127.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  128.      */
  129.     private ?string $total_tax_amount null;
  130.     /**
  131.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  132.      */
  133.     private ?string $total_amount null;
  134.     /**
  135.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  136.      */
  137.     private ?string $residual null;
  138.     /**
  139.      * @ORM\Column(type="json")
  140.      */
  141.     private array $options = [];
  142.     /**
  143.      * @ORM\OneToMany(
  144.      *      targetEntity=CreditNoteLine::class,
  145.      *      mappedBy="credit_note",
  146.      *      cascade={"persist", "remove"},
  147.      *      fetch="EXTRA_LAZY"
  148.      * )
  149.      * @ORM\OrderBy({"position" = "ASC"})
  150.      */
  151.     private Collection $lines;
  152.     /**
  153.      * @ORM\OneToMany(targetEntity=DocumentPayment::class, mappedBy="credit_note", fetch="EXTRA_LAZY")
  154.      */
  155.     private Collection $payments;
  156.     /**
  157.      * @ORM\OneToMany(targetEntity=Invoice::class, mappedBy="credit_note")
  158.      */
  159.     private Collection $invoices;
  160.     /**
  161.      * @ORM\ManyToOne(targetEntity=Establishment::class)
  162.      */
  163.     private ?Establishment $establishment null;
  164.     public function __construct()
  165.     {
  166.         $this->lines = new ArrayCollection();
  167.         $this->payments = new ArrayCollection();
  168.         $this->invoices = new ArrayCollection();
  169.     }
  170.     /**
  171.      * @return Uuid|null
  172.      */
  173.     public function getId(): ?Uuid
  174.     {
  175.         return $this->id;
  176.     }
  177.     /**
  178.      * @return CreditNote
  179.      */
  180.     public function setId(): self
  181.     {
  182.         $this->id null;
  183.         return $this;
  184.     }
  185.     /**
  186.      * @return Context|null
  187.      */
  188.     public function getContext(): ?Context
  189.     {
  190.         return $this->context;
  191.     }
  192.     /**
  193.      * @param Context|null $context
  194.      * @return CreditNote
  195.      */
  196.     public function setContext(?Context $context): self
  197.     {
  198.         $this->context $context;
  199.         return $this;
  200.     }
  201.     /**
  202.      * @return Customer|null
  203.      * @throws NonUniqueResultException
  204.      */
  205.     public function getCustomer(): ?Customer
  206.     {
  207.         if ($this->em && $this->customer) {
  208.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  209.             $customer $this->em->getRepository(Customer::class)
  210.                 ->createQueryBuilder('c')
  211.                 ->where('c.id = :customerId')
  212.                 ->setParameter('customerId'$this->customer->getId()->toBinary())
  213.                 ->getQuery()
  214.                 ->getOneOrNullResult();
  215.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  216.             return $customer;
  217.         }
  218.         return $this->customer;
  219.     }
  220.     /**
  221.      * @param Customer $customer
  222.      * @return CreditNote
  223.      */
  224.     public function setCustomer(Customer $customer): self
  225.     {
  226.         if ($this->customer && $this->customer->getId() !== $customer->getId()) {
  227.             $this->setInvoiceContact(null)->setDeliveryContact(null);
  228.         }
  229.         $this->customer $customer;
  230.         $this->setDeliveryAddress(null);
  231.         return $this->setInvoiceAddress($customer);
  232.     }
  233.     /**
  234.      * @return User|null
  235.      * @throws NonUniqueResultException
  236.      */
  237.     public function getCommercial(): ?User
  238.     {
  239.         if ($this->em && $this->commercial) {
  240.             SoftdeleteFilter::disable($this->em, [User::class]);
  241.             $commercial $this->em->getRepository(User::class)
  242.                 ->createQueryBuilder('u')
  243.                 ->where('u.id = :commercialId')
  244.                 ->setParameter('commercialId'$this->commercial->getId()->toBinary())
  245.                 ->getQuery()
  246.                 ->getOneOrNullResult();
  247.             SoftdeleteFilter::enable($this->em, [User::class]);
  248.             return $commercial;
  249.         }
  250.         return $this->commercial;
  251.     }
  252.     /**
  253.      * @param User|null $commercial
  254.      * @return CreditNote
  255.      */
  256.     public function setCommercial(?User $commercial): self
  257.     {
  258.         $this->commercial $commercial;
  259.         return $this;
  260.     }
  261.     /**
  262.      * @return Customer|null
  263.      * @throws NonUniqueResultException
  264.      */
  265.     public function getInvoiceAddress(): ?Customer
  266.     {
  267.         if ($this->em && $this->invoice_address) {
  268.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  269.             $invoiceAddress $this->em->getRepository(Customer::class)
  270.                 ->createQueryBuilder('c')
  271.                 ->where('c.id = :invoiceAddressId')
  272.                 ->setParameter('invoiceAddressId'$this->invoice_address->getId()->toBinary())
  273.                 ->getQuery()
  274.                 ->getOneOrNullResult();
  275.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  276.             return $invoiceAddress;
  277.         }
  278.         return $this->invoice_address;
  279.     }
  280.     /**
  281.      * @param Customer|null $invoice_address
  282.      * @return CreditNote
  283.      */
  284.     public function setInvoiceAddress(?Customer $invoice_address): self
  285.     {
  286.         $this->invoice_address $invoice_address;
  287.         return $this;
  288.     }
  289.     /**
  290.      * @return Customer|null
  291.      * @throws NonUniqueResultException
  292.      */
  293.     public function getDeliveryAddress(): ?Customer
  294.     {
  295.         if ($this->em && $this->delivery_address) {
  296.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  297.             $deliveryAddress $this->em->getRepository(Customer::class)
  298.                 ->createQueryBuilder('c')
  299.                 ->where('c.id = :deliveryAddressId')
  300.                 ->setParameter('deliveryAddressId'$this->delivery_address->getId()->toBinary())
  301.                 ->getQuery()
  302.                 ->getOneOrNullResult();
  303.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  304.             return $deliveryAddress;
  305.         }
  306.         return $this->delivery_address;
  307.     }
  308.     /**
  309.      * @param Customer|null $delivery_address
  310.      * @return CreditNote
  311.      */
  312.     public function setDeliveryAddress(?Customer $delivery_address): self
  313.     {
  314.         $this->delivery_address $delivery_address;
  315.         return $this;
  316.     }
  317.     /**
  318.      * @return Customer|null
  319.      * @throws NonUniqueResultException
  320.      */
  321.     public function getInvoiceContact(): ?Customer
  322.     {
  323.         if ($this->em && $this->invoiceContact) {
  324.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  325.             $invoiceContact $this->em->getRepository(Customer::class)
  326.                 ->createQueryBuilder('c')
  327.                 ->where('c.id = :invoiceContactId')
  328.                 ->setParameter('invoiceContactId'$this->invoiceContact->getId()->toBinary())
  329.                 ->getQuery()
  330.                 ->getOneOrNullResult();
  331.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  332.             return $invoiceContact;
  333.         }
  334.         return $this->invoiceContact;
  335.     }
  336.     /**
  337.      * @param Customer|null $invoiceContact
  338.      * @return CreditNote
  339.      */
  340.     public function setInvoiceContact(?Customer $invoiceContact): CreditNote
  341.     {
  342.         $this->invoiceContact $invoiceContact;
  343.         return $this;
  344.     }
  345.     /**
  346.      * @return Customer|null
  347.      * @throws NonUniqueResultException
  348.      */
  349.     public function getDeliveryContact(): ?Customer
  350.     {
  351.         if ($this->em && $this->deliveryContact) {
  352.             SoftdeleteFilter::disable($this->em, [Customer::class]);
  353.             $deliveryContact $this->em->getRepository(Customer::class)
  354.                 ->createQueryBuilder('c')
  355.                 ->where('c.id = :deliveryContactId')
  356.                 ->setParameter('deliveryContactId'$this->deliveryContact->getId()->toBinary())
  357.                 ->getQuery()
  358.                 ->getOneOrNullResult();
  359.             SoftdeleteFilter::enable($this->em, [Customer::class]);
  360.             return $deliveryContact;
  361.         }
  362.         return $this->deliveryContact;
  363.     }
  364.     /**
  365.      * @param Customer|null $deliveryContact
  366.      * @return CreditNote
  367.      */
  368.     public function setDeliveryContact(?Customer $deliveryContact): CreditNote
  369.     {
  370.         $this->deliveryContact $deliveryContact;
  371.         return $this;
  372.     }
  373.     /**
  374.      * @return Invoice|null
  375.      * @throws NonUniqueResultException
  376.      */
  377.     public function getInvoice(): ?Invoice
  378.     {
  379.         if ($this->em && $this->invoice) {
  380.             SoftdeleteFilter::disable($this->em, [Invoice::class]);
  381.             $invoice $this->em->getRepository(Invoice::class)
  382.                 ->createQueryBuilder('i')
  383.                 ->where('i.id = :invoiceId')
  384.                 ->setParameter('invoiceId'$this->invoice->getId()->toBinary())
  385.                 ->getQuery()
  386.                 ->getOneOrNullResult();
  387.             SoftdeleteFilter::enable($this->em, [Invoice::class]);
  388.             return $invoice;
  389.         }
  390.         return $this->invoice;
  391.     }
  392.     /**
  393.      * @param Invoice|null $invoice
  394.      * @param bool|null $onlyInvoice
  395.      * @return CreditNote
  396.      * @throws NonUniqueResultException
  397.      */
  398.     public function setInvoice(?Invoice $invoice, ?bool $onlyInvoice false): self
  399.     {
  400.         $this->invoice $invoice;
  401.         if ($invoice && !$onlyInvoice) {
  402.             $this->setCustomer($invoice->getCustomer());
  403.             $this->setCommercial($invoice->getCommercial());
  404.             $this->setInvoiceAddress($invoice->getInvoiceAddress());
  405.             $this->setDeliveryAddress($invoice->getDeliveryAddress());
  406.             $this->setInvoiceContact($invoice->getInvoiceContact());
  407.             $this->setDeliveryContact($invoice->getDeliveryContact());
  408.             $this->setTotalAmountUntaxed($invoice->getResidual());
  409.             $this->setTotalAmount($invoice->getResidual());
  410.             $this->setCurrency($invoice->getCurrency());
  411.             $this->setContext($invoice->getContext());
  412.             $this->setEstablishment($invoice->getEstablishment());
  413.             $this->setExternalName($invoice->getExternalName());
  414.             if (!empty($invoice->getOptions()['note'])) {
  415.                 $this->addOptions([
  416.                     'note' => $invoice->getOptions()['note']
  417.                 ]);
  418.             }
  419.             if (!empty($invoice->getOptions()['customerNote'])) {
  420.                 $this->addOptions([
  421.                     'customerNote' => $invoice->getOptions()['customerNote']
  422.                 ]);
  423.             }
  424.         }
  425.         return $this;
  426.     }
  427.     /**
  428.      * @return Currency|null
  429.      */
  430.     public function getCurrency(): ?Currency
  431.     {
  432.         return $this->currency;
  433.     }
  434.     /**
  435.      * @param Currency $currency
  436.      * @return CreditNote
  437.      */
  438.     public function setCurrency(Currency $currency): self
  439.     {
  440.         $this->currency $currency;
  441.         return $this->setCurrencyChangeRate($currency->getChangeRate());
  442.     }
  443.     /**
  444.      * @return string|null
  445.      */
  446.     public function getCurrencyChangeRate(): ?string
  447.     {
  448.         return $this->currency_change_rate;
  449.     }
  450.     /**
  451.      * @param string|null $currency_change_rate
  452.      * @return CreditNote
  453.      */
  454.     public function setCurrencyChangeRate(?string $currency_change_rate): self
  455.     {
  456.         $this->currency_change_rate $currency_change_rate;
  457.         return $this;
  458.     }
  459.     /**
  460.      * @return PaymentMethod|null
  461.      * @throws NonUniqueResultException
  462.      */
  463.     public function getPaymentMethod(): ?PaymentMethod
  464.     {
  465.         if ($this->em && $this->payment_method) {
  466.             SoftdeleteFilter::disable($this->em, [PaymentMethod::class]);
  467.             $payment_method $this->em->getRepository(PaymentMethod::class)
  468.                 ->createQueryBuilder('pm')
  469.                 ->where('pm.id = :paymentMethodId')
  470.                 ->setParameter('paymentMethodId'$this->payment_method->getId()->toBinary())
  471.                 ->getQuery()
  472.                 ->getOneOrNullResult();
  473.             SoftdeleteFilter::enable($this->em, [PaymentMethod::class]);
  474.             return $payment_method;
  475.         }
  476.         return $this->payment_method;
  477.     }
  478.     /**
  479.      * @param PaymentMethod|null $payment_method
  480.      */
  481.     public function setPaymentMethod(?PaymentMethod $payment_method): void
  482.     {
  483.         $this->payment_method $payment_method;
  484.     }
  485.     /**
  486.      * @return string|null
  487.      */
  488.     public function getReference(): ?string
  489.     {
  490.         return $this->reference;
  491.     }
  492.     /**
  493.      * @param string|null $reference
  494.      * @return CreditNote
  495.      */
  496.     public function setReference(?string $reference): self
  497.     {
  498.         $this->reference $reference;
  499.         return $this;
  500.     }
  501.     /**
  502.      * @return string|null
  503.      */
  504.     public function getInternalName(): ?string
  505.     {
  506.         return $this->internal_name;
  507.     }
  508.     /**
  509.      * @param string|null $internal_name
  510.      * @return CreditNote
  511.      */
  512.     public function setInternalName(?string $internal_name): self
  513.     {
  514.         $this->internal_name $internal_name;
  515.         return $this;
  516.     }
  517.     /**
  518.      * @return string|null
  519.      */
  520.     public function getExternalName(): ?string
  521.     {
  522.         return $this->external_name;
  523.     }
  524.     /**
  525.      * @param string|null $external_name
  526.      * @return CreditNote
  527.      */
  528.     public function setExternalName(?string $external_name): self
  529.     {
  530.         $this->external_name $external_name;
  531.         return $this;
  532.     }
  533.     /**
  534.      * @return bool
  535.      */
  536.     public function isReducedVat(): bool
  537.     {
  538.         return $this->reduced_vat;
  539.     }
  540.     /**
  541.      * @param bool $reduced_vat
  542.      * @return CreditNote
  543.      */
  544.     public function setReducedVat(bool $reduced_vat): self
  545.     {
  546.         $this->reduced_vat $reduced_vat;
  547.         return $this;
  548.     }
  549.     /**
  550.      * @return string|null
  551.      */
  552.     public function getTotalAmountUntaxed(): ?string
  553.     {
  554.         return $this->total_amount_untaxed;
  555.     }
  556.     /**
  557.      * @param string|null $total_amount_untaxed
  558.      * @return CreditNote
  559.      */
  560.     public function setTotalAmountUntaxed(?string $total_amount_untaxed): self
  561.     {
  562.         $this->total_amount_untaxed $total_amount_untaxed;
  563.         return $this;
  564.     }
  565.     /**
  566.      * @return string|null
  567.      */
  568.     public function getTotalTaxAmount(): ?string
  569.     {
  570.         return $this->total_tax_amount;
  571.     }
  572.     /**
  573.      * @param string|null $total_tax_amount
  574.      * @return CreditNote
  575.      */
  576.     public function setTotalTaxAmount(?string $total_tax_amount): self
  577.     {
  578.         $this->total_tax_amount $total_tax_amount;
  579.         return $this;
  580.     }
  581.     /**
  582.      * @return string|null
  583.      */
  584.     public function getTotalAmount(): ?string
  585.     {
  586.         return $this->total_amount;
  587.     }
  588.     /**
  589.      * @param string|null $total_amount
  590.      * @return CreditNote
  591.      */
  592.     public function setTotalAmount(?string $total_amount): self
  593.     {
  594.         $this->total_amount $total_amount;
  595.         return $this;
  596.     }
  597.     /**
  598.      * @return string|null
  599.      */
  600.     public function getResidual(): ?string
  601.     {
  602.         return $this->residual;
  603.     }
  604.     /**
  605.      * @param string|null $residual
  606.      * @return CreditNote
  607.      */
  608.     public function setResidual(?string $residual): self
  609.     {
  610.         $this->residual $residual;
  611.         return $this;
  612.     }
  613.     /**
  614.      * @return array
  615.      */
  616.     public function getOptions(): array
  617.     {
  618.         return $this->options;
  619.     }
  620.     /**
  621.      * @param array $options
  622.      * @return CreditNote
  623.      */
  624.     public function setOptions(array $options): self
  625.     {
  626.         $this->options $options;
  627.         return $this;
  628.     }
  629.     /**
  630.      * @param array $options
  631.      * @return CreditNote
  632.      */
  633.     public function addOptions(array $options): self
  634.     {
  635.         return $this->setOptions(array_merge($this->options$options));
  636.     }
  637.     /**
  638.      * @return Collection|CreditNoteLine[]
  639.      */
  640.     public function getLines(): Collection
  641.     {
  642.         return $this->getFilterLines();
  643.     }
  644.     /**
  645.      * @param CreditNoteLine $line
  646.      * @return CreditNote
  647.      */
  648.     public function addLine(CreditNoteLine $line): self
  649.     {
  650.         if (!$this->lines->contains($line)) {
  651.             $this->lines[] = $line;
  652.             if ($line->getCreditNote() !== $this) {
  653.                 $line->setCreditNote($this);
  654.             }
  655.         }
  656.         return $this;
  657.     }
  658.     /**
  659.      * @param CreditNoteLine $line
  660.      * @return CreditNote
  661.      */
  662.     public function removeLine(CreditNoteLine $line): self
  663.     {
  664.         $this->lines->removeElement($line);
  665.         return $this;
  666.     }
  667.     /**
  668.      * @param bool $withGroups
  669.      * @param bool $all
  670.      * @param bool $withPacks
  671.      * @return Collection|CreditNoteLine[]
  672.      */
  673.     public function getFilterLines(bool $withGroups truebool $all falsebool $withPacks true): Collection
  674.     {
  675.         if ($all) {
  676.             $lines $this->lines;
  677.             $goodLines = [];
  678.             foreach ($lines as $line) {
  679.                 if (!$line->getParent() && !$line->getPackParent()) {
  680.                     $goodLines[] = $line;
  681.                     foreach ($line->getChildrens() as $child) {
  682.                         $goodLines[] = $child;
  683.                         foreach ($child->getPackChildrens() as $grandChild) {
  684.                             $goodLines[] = $grandChild;
  685.                         }
  686.                     }
  687.                     foreach ($line->getPackChildrens() as $child) {
  688.                         $goodLines[] = $child;
  689.                     }
  690.                 }
  691.             }
  692.             return new ArrayCollection($goodLines);
  693.         }
  694.         $criteria Criteria::create();
  695.         if ($withGroups) {
  696.             $criteria
  697.                 ->where(Criteria::expr()->eq('parent'null))
  698.                 ->andWhere(Criteria::expr()->eq('packParent'null));
  699.         } else {
  700.             if ($withPacks) {
  701.                 $criteria->andWhere(Criteria::expr()->eq('is_pack'true));
  702.             } else {
  703.                 $criteria->andWhere(Criteria::expr()->eq('is_pack'false));
  704.             }
  705.             $criteria->where(Criteria::expr()->eq('is_group'false));
  706.         }
  707.         return $this->lines->matching($criteria);
  708.     }
  709.     /**
  710.      * @return Collection|DocumentPayment[]
  711.      */
  712.     public function getPayments(): Collection
  713.     {
  714.         return $this->payments;
  715.     }
  716.     /**
  717.      * @return bool
  718.      */
  719.     public function isCancelable(): bool
  720.     {
  721.         return !$this->getCanceledAt() && $this->getResidual() > && $this->getResidual() == $this->getTotalAmount();
  722.     }
  723.     /**
  724.      * @return CreditNote
  725.      * @throws NonUniqueResultException
  726.      */
  727.     public function duplicate(): CreditNote
  728.     {
  729.         if ($this->id) {
  730.             $clone = clone $this;
  731.             $clone->setId();
  732.             $clone->setCreatedAt(new DateTime());
  733.             $clone->setCreatedBy(null);
  734.             $clone->setUpdatedAt(new DateTime());
  735.             $clone->setUpdatedBy(null);
  736.             $clone->setValidatedAt(null);
  737.             $clone->setValidatedBy(null);
  738.             $clone->setCanceledAt(null);
  739.             $clone->setCanceledBy(null);
  740.             $clone->setContext(null);
  741.             $clone->setEstablishment(null);
  742.             $clone->setInvoice(null);
  743.             $clone->setReference(null);
  744.             $clone->setResidual(null);
  745.             $clone->addOptions([
  746.                 'invoice_address' => null,
  747.                 'delivery_address' => null
  748.             ]);
  749.             $clone->lines = new ArrayCollection();
  750.             foreach ($this->getFilterLines() as $line) {
  751.                 $clone_line $line->duplicate($clone);
  752.                 $clone->addLine($clone_line);
  753.             }
  754.             return $clone;
  755.         }
  756.         return $this;
  757.     }
  758.     /**
  759.      * @return Establishment|null
  760.      */
  761.     public function getEstablishment(): ?Establishment
  762.     {
  763.         return $this->establishment;
  764.     }
  765.     /**
  766.      * @param Establishment|null $establishment
  767.      * @return $this
  768.      */
  769.     public function setEstablishment(?Establishment $establishment): self
  770.     {
  771.         $this->establishment $establishment;
  772.         return $this;
  773.     }
  774.     /**
  775.      * @return Collection
  776.      */
  777.     public function getInvoices(): Collection
  778.     {
  779.         return $this->invoices;
  780.     }
  781. }