vendor/bluue/sales-bundle/src/Entity/CreditNoteLine.php line 39

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 DateTime;
  12. use App\Entity\TaxRule;
  13. use Doctrine\ORM\NonUniqueResultException;
  14. use Symfony\Component\Uid\Uuid;
  15. use Doctrine\ORM\Mapping as ORM;
  16. use Gedmo\Mapping\Annotation as Gedmo;
  17. use Doctrine\Common\Collections\Collection;
  18. use Doctrine\Common\Collections\ArrayCollection;
  19. use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
  20. use Bluue\SalesBundle\Repository\CreditNoteLineRepository;
  21. use App\DoctrineExtensions\Timestampable\Traits\UserTimestampableEntity;
  22. use App\DoctrineExtensions\SoftDeleteable\Traits\UserSoftDeleteableEntity;
  23. use Bluue\ProductsBundle\Entity\Declination;
  24. use Bluue\ProductsBundle\Entity\Product;
  25. /**
  26.  * @ORM\Entity(repositoryClass=CreditNoteLineRepository::class)
  27.  * @ORM\Table(name="sales_bundle__credit_note_line", indexes={
  28.  *  @ORM\Index(name="deleted_at", columns={"deleted_at"}),
  29.  *  @ORM\Index(name="created_at", columns={"created_at"}),
  30.  *  @ORM\Index(name="updated_at", columns={"updated_at"})
  31.  * })
  32.  * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
  33.  */
  34. class CreditNoteLine
  35. {
  36.     use UserTimestampableEntity;
  37.     use UserSoftDeleteableEntity;
  38.     use EntityManagerServiceEntity;
  39.     /**
  40.      * @ORM\Id
  41.      * @ORM\Column(type="uuid")
  42.      * @ORM\GeneratedValue(strategy="CUSTOM")
  43.      * @ORM\CustomIdGenerator(class=UuidGenerator::class)
  44.      */
  45.     private ?Uuid $id null;
  46.     /**
  47.      * @ORM\ManyToOne(targetEntity=CreditNote::class, inversedBy="lines")
  48.      * @ORM\JoinColumn(nullable=false)
  49.      */
  50.     private ?CreditNote $credit_note null;
  51.     /**
  52.      * @ORM\ManyToOne(targetEntity=LineType::class)
  53.      */
  54.     private ?LineType $line_type null;
  55.     /**
  56.      * @ORM\ManyToOne(targetEntity=TaxRule::class)
  57.      */
  58.     private ?TaxRule $tax_rule null;
  59.     /**
  60.      * @ORM\ManyToOne(targetEntity="CreditNoteLine", inversedBy="childrens")
  61.      * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
  62.      */
  63.     private ?CreditNoteLine $parent null;
  64.     /**
  65.      * @ORM\Column(type="boolean")
  66.      */
  67.     private bool $is_group false;
  68.     /**
  69.      * @ORM\ManyToOne(targetEntity="CreditNoteLine", inversedBy="packChildrens")
  70.      * @ORM\JoinColumn(name="pack_parent_id", referencedColumnName="id")
  71.      */
  72.     private ?CreditNoteLine $packParent null;
  73.     /**
  74.      * @ORM\Column(type="boolean")
  75.      */
  76.     private bool $is_pack false;
  77.     /**
  78.      * @ORM\Column(type="string", length=128, nullable="true")
  79.      */
  80.     private ?string $reference null;
  81.     /**
  82.      * @ORM\Column(type="string", length=128, nullable="true")
  83.      */
  84.     private ?string $referenceBrand null;
  85.     /**
  86.      * @ORM\Column(type="string", length=255, nullable="true")
  87.      */
  88.     private ?string $name null;
  89.     /**
  90.      * @ORM\Column(type="text", nullable="true")
  91.      */
  92.     private ?string $description null;
  93.     /**
  94.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  95.      */
  96.     private ?string $unit_price null;
  97.     /**
  98.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  99.      */
  100.     private ?string $unitPriceWithTax null;
  101.     /**
  102.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  103.      */
  104.     private ?string $quantity null;
  105.     /**
  106.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  107.      */
  108.     private ?string $wholesale_price null;
  109.     /**
  110.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  111.      */
  112.     private ?string $margin_ratio null;
  113.     /**
  114.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  115.      */
  116.     private ?string $total_amount_untaxed null;
  117.     /**
  118.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  119.      */
  120.     private ?string $total_tax_amount null;
  121.     /**
  122.      * @ORM\Column(type="decimal", precision=20, scale=6, nullable="true")
  123.      */
  124.     private ?string $total_amount null;
  125.     /**
  126.      * @ORM\Column(type="integer")
  127.      */
  128.     private ?int $position null;
  129.     /**
  130.      * @ORM\Column(type="json")
  131.      */
  132.     private array $options = [];
  133.     /**
  134.      * @ORM\OneToMany(
  135.      *      targetEntity="CreditNoteLine",
  136.      *      mappedBy="parent",
  137.      *      cascade={"persist", "remove"},
  138.      *      fetch="EXTRA_LAZY"
  139.      * )
  140.      * @ORM\OrderBy({"position" = "ASC"})
  141.      */
  142.     private Collection $childrens;
  143.     /**
  144.      * @ORM\OneToMany(
  145.      *      targetEntity="CreditNoteLine",
  146.      *      mappedBy="packParent",
  147.      *      cascade={"persist", "remove"},
  148.      *      fetch="EXTRA_LAZY"
  149.      * )
  150.      * @ORM\OrderBy({"position" = "ASC"})
  151.      */
  152.     private Collection $packChildrens;
  153.     /**
  154.      * @ORM\ManyToOne(targetEntity=Product::class)
  155.      */
  156.     private ?Product $product null;
  157.     /**
  158.      * @ORM\ManyToOne(targetEntity=Declination::class)
  159.      */
  160.     private ?Declination $declination null;
  161.     public function __construct()
  162.     {
  163.         $this->childrens = new ArrayCollection();
  164.         $this->packChildrens = new ArrayCollection();
  165.     }
  166.     /**
  167.      * @return Uuid|null
  168.      */
  169.     public function getId(): ?Uuid
  170.     {
  171.         return $this->id;
  172.     }
  173.     /**
  174.      * @return CreditNoteLine
  175.      */
  176.     public function setId(): self
  177.     {
  178.         $this->id null;
  179.         return $this;
  180.     }
  181.     /**
  182.      * @return CreditNote|null
  183.      */
  184.     public function getCreditNote(): ?CreditNote
  185.     {
  186.         return $this->credit_note;
  187.     }
  188.     /**
  189.      * @param CreditNote $credit_note
  190.      * @return CreditNoteLine
  191.      */
  192.     public function setCreditNote(CreditNote $credit_note): self
  193.     {
  194.         $this->credit_note $credit_note;
  195.         return $this;
  196.     }
  197.     /**
  198.      * @return LineType|null
  199.      */
  200.     public function getLineType(): ?LineType
  201.     {
  202.         return $this->line_type;
  203.     }
  204.     /**
  205.      * @param LineType|null $line_type
  206.      * @return CreditNoteLine
  207.      */
  208.     public function setLineType(?LineType $line_type): self
  209.     {
  210.         $this->line_type $line_type;
  211.         return $this;
  212.     }
  213.     /**
  214.      * @return TaxRule|null
  215.      * @throws NonUniqueResultException
  216.      */
  217.     public function getTaxRule(): ?TaxRule
  218.     {
  219.         if ($this->em && $this->tax_rule) {
  220.             SoftdeleteFilter::disable($this->em, [TaxRule::class]);
  221.             $taxRule $this->em->getRepository(TaxRule::class)
  222.                 ->createQueryBuilder('tr')
  223.                 ->where('tr.id = :taxRuleId')
  224.                 ->setParameter('taxRuleId'$this->tax_rule->getId()->toBinary())
  225.                 ->getQuery()
  226.                 ->getOneOrNullResult();
  227.             SoftdeleteFilter::enable($this->em, [TaxRule::class]);
  228.             return $taxRule;
  229.         }
  230.         return $this->tax_rule;
  231.     }
  232.     /**
  233.      * @param TaxRule|null $tax_rule
  234.      * @return CreditNoteLine
  235.      */
  236.     public function setTaxRule(?TaxRule $tax_rule): self
  237.     {
  238.         $this->tax_rule $tax_rule;
  239.         return $this;
  240.     }
  241.     /**
  242.      * @return CreditNoteLine|null
  243.      */
  244.     public function getParent(): ?CreditNoteLine
  245.     {
  246.         return $this->parent;
  247.     }
  248.     /**
  249.      * @param CreditNoteLine|null $parent
  250.      * @return CreditNoteLine
  251.      */
  252.     public function setParent(?CreditNoteLine $parent): self
  253.     {
  254.         $this->parent $parent;
  255.         return $this;
  256.     }
  257.     /**
  258.      * @return bool
  259.      */
  260.     public function getIsGroup(): bool
  261.     {
  262.         return $this->is_group;
  263.     }
  264.     /**
  265.      * @param bool $is_group
  266.      * @return CreditNoteLine
  267.      */
  268.     public function setIsGroup(bool $is_group): self
  269.     {
  270.         $this->is_group $is_group;
  271.         return $this;
  272.     }
  273.     /**
  274.      * @return CreditNoteLine|null
  275.      */
  276.     public function getPackParent(): ?CreditNoteLine
  277.     {
  278.         return $this->packParent;
  279.     }
  280.     /**
  281.      * @param CreditNoteLine|null $packParent
  282.      * @return CreditNoteLine
  283.      */
  284.     public function setPackParent(?CreditNoteLine $packParent): self
  285.     {
  286.         $this->packParent $packParent;
  287.         return $this;
  288.     }
  289.     /**
  290.      * @return bool
  291.      */
  292.     public function getIsPack(): bool
  293.     {
  294.         return $this->is_pack;
  295.     }
  296.     /**
  297.      * @param bool $is_pack
  298.      * @return CreditNoteLine
  299.      */
  300.     public function setIsPack(bool $is_pack): self
  301.     {
  302.         $this->is_pack $is_pack;
  303.         return $this;
  304.     }
  305.     /**
  306.      * @return string|null
  307.      */
  308.     public function getReference(): ?string
  309.     {
  310.         return $this->reference;
  311.     }
  312.     /**
  313.      * @param string|null $reference
  314.      * @return CreditNoteLine
  315.      */
  316.     public function setReference(?string $reference): self
  317.     {
  318.         $this->reference $reference;
  319.         return $this;
  320.     }
  321.     /**
  322.      * @return string|null
  323.      */
  324.     public function getReferenceBrand(): ?string
  325.     {
  326.         return $this->referenceBrand;
  327.     }
  328.     /**
  329.      * @param string|null $referenceBrand
  330.      * @return CreditNoteLine
  331.      */
  332.     public function setReferenceBrand(?string $referenceBrand): self
  333.     {
  334.         $this->referenceBrand $referenceBrand;
  335.         return $this;
  336.     }
  337.     /**
  338.      * @return string|null
  339.      */
  340.     public function getName(): ?string
  341.     {
  342.         return $this->name;
  343.     }
  344.     /**
  345.      * @param string|null $name
  346.      * @return CreditNoteLine
  347.      */
  348.     public function setName(?string $name): self
  349.     {
  350.         $this->name $name;
  351.         return $this;
  352.     }
  353.     /**
  354.      * @return string|null
  355.      */
  356.     public function getDescription(): ?string
  357.     {
  358.         return $this->description;
  359.     }
  360.     /**
  361.      * @param string|null $description
  362.      * @return CreditNoteLine
  363.      */
  364.     public function setDescription(?string $description): self
  365.     {
  366.         $this->description $description;
  367.         return $this;
  368.     }
  369.     /**
  370.      * @return string|null
  371.      */
  372.     public function getUnitPrice(): ?string
  373.     {
  374.         return $this->unit_price;
  375.     }
  376.     /**
  377.      * @param string|null $unit_price
  378.      * @return CreditNoteLine
  379.      */
  380.     public function setUnitPrice(?string $unit_price): self
  381.     {
  382.         $this->unit_price $unit_price;
  383.         return $this;
  384.     }
  385.     /**
  386.      * @return string|null
  387.      */
  388.     public function getUnitPriceWithTax(): ?string
  389.     {
  390.         return $this->unitPriceWithTax;
  391.     }
  392.     /**
  393.      * @param string|null $unitPriceWithTax
  394.      * @return CreditNoteLine
  395.      */
  396.     public function setUnitPriceWithTax(?string $unitPriceWithTax): CreditNoteLine
  397.     {
  398.         $this->unitPriceWithTax $unitPriceWithTax;
  399.         return $this;
  400.     }
  401.     /**
  402.      * @return string|null
  403.      */
  404.     public function getQuantity(): ?string
  405.     {
  406.         return $this->quantity;
  407.     }
  408.     /**
  409.      * @param string|null $quantity
  410.      * @return CreditNoteLine
  411.      */
  412.     public function setQuantity(?string $quantity): self
  413.     {
  414.         $this->quantity $quantity;
  415.         return $this;
  416.     }
  417.     /**
  418.      * @return string|null
  419.      */
  420.     public function getWholesalePrice(): ?string
  421.     {
  422.         return $this->wholesale_price;
  423.     }
  424.     /**
  425.      * @param string|null $wholesale_price
  426.      * @return CreditNoteLine
  427.      */
  428.     public function setWholesalePrice(?string $wholesale_price): self
  429.     {
  430.         $this->wholesale_price $wholesale_price;
  431.         return $this;
  432.     }
  433.     /**
  434.      * @return string|null
  435.      */
  436.     public function getMarginRatio(): ?string
  437.     {
  438.         return $this->margin_ratio;
  439.     }
  440.     /**
  441.      * @param string|null $margin_ratio
  442.      * @return CreditNoteLine
  443.      */
  444.     public function setMarginRatio(?string $margin_ratio): self
  445.     {
  446.         $this->margin_ratio $margin_ratio;
  447.         return $this;
  448.     }
  449.     /**
  450.      * @param bool $calcWithPackaging
  451.      * @return float|null
  452.      */
  453.     public function getTotalMargin(bool $calcWithPackaging false): ?float
  454.     {
  455.         if ($this->wholesale_price === null) {
  456.             return 0;
  457.         }
  458.         if ($calcWithPackaging && !empty($this->options['unitQuantity'])) {
  459.             $quantity = (float) $this->options['unitQuantity'];
  460.         } else {
  461.             $quantity = (int) $this->quantity;
  462.         }
  463.         $sellPrice = (float) $this->total_amount_untaxed;
  464.         if (!empty($this->options['ecoPart']) && !empty($this->options['ecoPart']['amount'])) {
  465.             $sellPrice -= $this->options['ecoPart']['amount']  * $quantity;
  466.         }
  467.         return $sellPrice - (float) $this->wholesale_price $quantity;
  468.     }
  469.     /**
  470.      * @return string|null
  471.      */
  472.     public function getTotalAmountUntaxed(): ?string
  473.     {
  474.         return $this->total_amount_untaxed;
  475.     }
  476.     /**
  477.      * @param string|null $total_amount_untaxed
  478.      * @return CreditNoteLine
  479.      */
  480.     public function setTotalAmountUntaxed(?string $total_amount_untaxed): self
  481.     {
  482.         $this->total_amount_untaxed $total_amount_untaxed;
  483.         return $this;
  484.     }
  485.     /**
  486.      * @return string|null
  487.      */
  488.     public function getTotalTaxAmount(): ?string
  489.     {
  490.         return $this->total_tax_amount;
  491.     }
  492.     /**
  493.      * @param string|null $total_tax_amount
  494.      * @return CreditNoteLine
  495.      */
  496.     public function setTotalTaxAmount(?string $total_tax_amount): self
  497.     {
  498.         $this->total_tax_amount $total_tax_amount;
  499.         return $this;
  500.     }
  501.     /**
  502.      * @return string|null
  503.      */
  504.     public function getTotalAmount(): ?string
  505.     {
  506.         return $this->total_amount;
  507.     }
  508.     /**
  509.      * @param string|null $total_amount
  510.      * @return CreditNoteLine
  511.      */
  512.     public function setTotalAmount(?string $total_amount): self
  513.     {
  514.         $this->total_amount $total_amount;
  515.         return $this;
  516.     }
  517.     /**
  518.      * @return int|null
  519.      */
  520.     public function getPosition(): ?int
  521.     {
  522.         return $this->position;
  523.     }
  524.     /**
  525.      * @param int|null $position
  526.      * @return CreditNoteLine
  527.      */
  528.     public function setPosition(?int $position): self
  529.     {
  530.         $this->position $position;
  531.         return $this;
  532.     }
  533.     /**
  534.      * @return array
  535.      */
  536.     public function getOptions(): array
  537.     {
  538.         return $this->options;
  539.     }
  540.     /**
  541.      * @param array $options
  542.      * @return CreditNoteLine
  543.      */
  544.     public function setOptions(array $options): self
  545.     {
  546.         $this->options $options;
  547.         return $this;
  548.     }
  549.     /**
  550.      * @param array $options
  551.      * @return CreditNoteLine
  552.      */
  553.     public function addOptions(array $options): self
  554.     {
  555.         return $this->setOptions(array_merge($this->options$options));
  556.     }
  557.     /**
  558.      * @return Collection|CreditNoteLine[]
  559.      */
  560.     public function getChildrens(): Collection
  561.     {
  562.         return $this->childrens;
  563.     }
  564.     /**
  565.      * @param CreditNoteLine $line
  566.      * @return CreditNoteLine
  567.      */
  568.     public function addChildren(CreditNoteLine $line): self
  569.     {
  570.         if (!$this->childrens->contains($line)) {
  571.             $this->childrens[] = $line;
  572.             $line->setParent($this);
  573.             if ($line->getCreditNote() !== $this->getCreditNote()) {
  574.                 $line->setCreditNote($this->getCreditNote());
  575.             }
  576.         }
  577.         return $this;
  578.     }
  579.     /**
  580.      * @return Collection|CreditNoteLine[]
  581.      */
  582.     public function getPackChildrens(): Collection
  583.     {
  584.         return $this->packChildrens;
  585.     }
  586.     /**
  587.      * @param CreditNoteLine $line
  588.      * @return $this
  589.      */
  590.     public function addPackChildren(CreditNoteLine $line): self
  591.     {
  592.         if (!$this->packChildrens->contains($line)) {
  593.             $this->packChildrens[] = $line;
  594.             $line->setPackParent($this);
  595.             if ($line->getCreditNote() !== $this->getCreditNote()) {
  596.                 $line->setCreditNote($this->getCreditNote());
  597.             }
  598.         }
  599.         return $this;
  600.     }
  601.     /**
  602.      * @return CreditNote|null
  603.      */
  604.     public function getDocument(): ?CreditNote
  605.     {
  606.         return $this->getCreditNote();
  607.     }
  608.     /**
  609.      * @param CreditNote $creditNote
  610.      * @return CreditNoteLine
  611.      */
  612.     public function duplicate(CreditNote $creditNote): CreditNoteLine
  613.     {
  614.         if ($this->id) {
  615.             $clone = clone $this;
  616.             $clone->setId();
  617.             $clone->setCreditNote($creditNote);
  618.             $clone->setCreatedAt(new DateTime());
  619.             $clone->setCreatedBy(null);
  620.             $clone->setUpdatedAt(new DateTime());
  621.             $clone->setUpdatedBy(null);
  622.             $clone->childrens = new ArrayCollection();
  623.             foreach ($this->getChildrens() as $children) {
  624.                 $clone_children $children->duplicate($creditNote);
  625.                 $clone->addChildren($clone_children);
  626.                 $children->packChildrens = new ArrayCollection();
  627.                 foreach ($children->getPackChildrens() as $packChildren) {
  628.                     $clone_pack_children $packChildren->duplicate($creditNote);
  629.                     $children->addPackChildren($clone_pack_children);
  630.                 }
  631.             }
  632.             $clone->packChildrens = new ArrayCollection();
  633.             foreach ($this->getPackChildrens() as $packChildren) {
  634.                 $clone_pack_children $packChildren->duplicate($creditNote);
  635.                 $clone->addPackChildren($clone_pack_children);
  636.             }
  637.             return $clone;
  638.         }
  639.         return $this;
  640.     }
  641.     /**
  642.      * @return bool
  643.      */
  644.     public function isProduct(): bool
  645.     {
  646.         $options $this->getOptions();
  647.         return !empty($options['product']) && !empty($options['product']['id']);
  648.     }
  649.     /**
  650.      * @return bool
  651.      */
  652.     public function isDeclination(): bool
  653.     {
  654.         return $this->isProduct() && !empty($this->getOptions()['product']['declination_id']);
  655.     }
  656.     /**
  657.      * @return Product|null
  658.      * @throws NonUniqueResultException
  659.      */
  660.     public function getProduct(): ?Product
  661.     {
  662.         if ($this->em && $this->product) {
  663.             SoftdeleteFilter::disable($this->em, [Product::class]);
  664.             $product $this->em->getRepository(Product::class)
  665.                 ->createQueryBuilder('p')
  666.                 ->where('p.id = :productId')
  667.                 ->setParameter('productId'$this->product->getId()->toBinary())
  668.                 ->getQuery()
  669.                 ->getOneOrNullResult();
  670.             SoftdeleteFilter::enable($this->em, [Product::class]);
  671.             return $product;
  672.         }
  673.         return $this->product;
  674.     }
  675.     /**
  676.      * @param Product|null $Product
  677.      * @return $this
  678.      */
  679.     public function setProduct(?Product $Product): self
  680.     {
  681.         $this->product $Product;
  682.         return $this;
  683.     }
  684.     /**
  685.      * @return Declination|null
  686.      * @throws NonUniqueResultException
  687.      */
  688.     public function getDeclination(): ?Declination
  689.     {
  690.         if ($this->em && $this->declination) {
  691.             SoftdeleteFilter::disable($this->em, [Declination::class]);
  692.             $declination $this->em->getRepository(Declination::class)
  693.                 ->createQueryBuilder('d')
  694.                 ->where('d.id = :declinationId')
  695.                 ->setParameter('declinationId'$this->declination->getId()->toBinary())
  696.                 ->getQuery()
  697.                 ->getOneOrNullResult();
  698.             SoftdeleteFilter::enable($this->em, [Declination::class]);
  699.             return $declination;
  700.         }
  701.         return $this->declination;
  702.     }
  703.     /**
  704.      * @param Declination|null $declination
  705.      * @return $this
  706.      */
  707.     public function setDeclination(?Declination $declination): self
  708.     {
  709.         $this->declination $declination;
  710.         return $this;
  711.     }
  712. }