src/Entity/Code.php line 20

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\History\Code\ChangeCarteCadeau;
  4. use App\Entity\History\Code\UpdateCarteCadeauHistory;
  5. use App\Entity\Payment\EmptyPayment;
  6. use App\Enum\TemplateCarteCadeau;
  7. use App\Repository\CodeRepository;
  8. use Doctrine\Common\Collections\ArrayCollection;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\Common\Collections\Criteria;
  11. use Doctrine\ORM\Mapping as ORM;
  12. use Doctrine\ORM\PersistentCollection;
  13. use App\Entity\History\Code\CarteCadeauHistory;
  14. /**
  15.  * @ORM\Entity(repositoryClass=CodeRepository::class)
  16.  */
  17. class Code
  18. {
  19.     /**
  20.      * @ORM\Id
  21.      * @ORM\GeneratedValue
  22.      * @ORM\Column(type="integer")
  23.      */
  24.     private $id;
  25.     /**
  26.      * @ORM\Column(type="string", length=255)
  27.      */
  28.     private $Type;
  29.     /**
  30.      * @ORM\Column(type="string", length=255, nullable=true)
  31.      */
  32.     private $Offer;
  33.     /**
  34.      * @ORM\Column(type="integer", nullable=true)
  35.      */
  36.     private $Solo;
  37.     /**
  38.      * @ORM\Column(type="integer", nullable=true)
  39.      */
  40.     private $Duo;
  41.     /**
  42.      * @ORM\Column(type="datetime")
  43.      */
  44.     private $validity;
  45.     /**
  46.      * @ORM\Column(type="string", length=255)
  47.      */
  48.     private $Value;
  49.     /**
  50.      * @ORM\Column(type="boolean")
  51.      */
  52.     private $used;
  53.     /**
  54.      * @ORM\Column(type="integer", nullable=true)
  55.      */
  56.     private $max_used;
  57.     /**
  58.      * @ORM\Column(type="integer", nullable=true)
  59.      */
  60.     private $count_used;
  61.     /**
  62.      * @ORM\Column(type="string", length=255, nullable=true)
  63.      */
  64.     private $services;
  65.     /**
  66.      * @ORM\Column(type="string", length=255, nullable=true)
  67.      */
  68.     private $comment;
  69.     /**
  70.      * @ORM\Column(type="string", length=255, enumType=TemplateCarteCadeau::class)
  71.      */
  72.     private TemplateCarteCadeau $templateCarteCadeau;
  73.     /**
  74.      * @ORM\OneToMany(targetEntity=Token::class, mappedBy="codePromo", cascade={"persist", "remove"})
  75.      */
  76.     private $token;
  77.     /**
  78.      * @ORM\Column(type="boolean", nullable=true)
  79.      */
  80.     private $physicalCard;
  81.     /**
  82.      * @ORM\OneToOne(targetEntity=DeliveryAddress::class, inversedBy="code", cascade={"persist", "remove"})
  83.      */
  84.     private $deliveryAddress;
  85.     /**
  86.      * @ORM\Column(type="float", nullable=true)
  87.      */
  88.     private $resteAPayer;
  89.     /**
  90.      * @ORM\ManyToOne(targetEntity=Reservation::class, inversedBy="createdCodes")
  91.      */
  92.     private $createdFromReservation;
  93.     /**
  94.      * @ORM\OneToMany(targetEntity=CarteCadeauHistory::class, mappedBy="code", cascade={"remove"})
  95.      */
  96.     private $carteCadeauHistories;
  97.     /**
  98.      * @ORM\Column(type="datetime", nullable=true)
  99.      */
  100.     private $createdAt;
  101.     /**
  102.      * Constructor
  103.      */
  104.     public function __construct()
  105.     {
  106.         $now = new \DateTime('now');
  107.         $this->used     false;
  108.         $this->validity $now->modify('+1 year')->setTime(235959);
  109.         $this->Value    str_replace(['O''0''o'], 'X'strtoupper(substr(str_repeat(md5(rand()), ceil(6/32)), 06)));
  110. //        $this->Value    = strtoupper(rtrim(strtr(base64_encode(random_bytes(5)), '+/', '-_'), '='));
  111.     }
  112.     public function getId(): ?int
  113.     {
  114.         return $this->id;
  115.     }
  116.     public function getType(): ?string
  117.     {
  118.         return $this->Type;
  119.     }
  120.     public function setType(string $Type): self
  121.     {
  122.         $this->Type $Type;
  123.         return $this;
  124.     }
  125.     public function getOffer(): ?string
  126.     {
  127.         return $this->Offer;
  128.     }
  129.     public function setOffer(?string $Offer): self
  130.     {
  131.         $this->Offer $Offer;
  132.         return $this;
  133.     }
  134.     public function getSolo(): ?int
  135.     {
  136.         return $this->Solo;
  137.     }
  138.     public function setSolo(?int $Solo): self
  139.     {
  140.         $this->Solo $Solo;
  141.         return $this;
  142.     }
  143.     public function getDuo(): ?int
  144.     {
  145.         return $this->Duo;
  146.     }
  147.     public function setDuo(?int $Duo): self
  148.     {
  149.         $this->Duo $Duo;
  150.         return $this;
  151.     }
  152.     public function getValidity(): ?\DateTimeInterface
  153.     {
  154.         return $this->validity;
  155.     }
  156.     public function getOriginalValidity(): ?\DateTimeInterface
  157.     {
  158.         $validityHistories = new ArrayCollection();
  159.         foreach($this->carteCadeauHistories as $carteCadeauHistory) {
  160.             if ($carteCadeauHistory instanceof UpdateCarteCadeauHistory) {
  161.                 foreach ($carteCadeauHistory->getChangeCarteCadeaux() as $changeCarteCadeau) {
  162.                     if ($changeCarteCadeau->getField() == "validity") {
  163.                         $validityHistories->add($carteCadeauHistory);
  164.                     }
  165.                 }
  166.             }
  167.         }
  168.         // If no history exists, current validity is the original
  169.         if ($validityHistories->isEmpty()) {
  170.             return $this->validity;
  171.         }
  172.         // Sort histories by creation date (oldest first)
  173.         $iterator $validityHistories->getIterator();
  174.         $iterator->uasort(function ($a$b) {
  175.             return $a->getCreatedAt() <=> $b->getCreatedAt();
  176.         });
  177.         $sortedHistories = new ArrayCollection(iterator_to_array($iterator));
  178.         // Get the first history entry (oldest change)
  179.         $oldestHistory $sortedHistories->first();
  180.         // Get the old value from the change record
  181.         foreach ($oldestHistory->getChangeCarteCadeaux() as $change) {
  182.             if ($change->getField() == "validity") {
  183.                 return new \DateTime($change->getOldValue());
  184.             }
  185.         }
  186.         // Fallback to current validity if something went wrong
  187.         return $this->validity;
  188.     }
  189.     public function getValidityFormated($modifier null): string
  190.     {
  191.         $months = [
  192.             'January' => 'janvier',
  193.             'February' => 'février',
  194.             'March' => 'mars',
  195.             'April' => 'avril',
  196.             'May' => 'mai',
  197.             'June' => 'juin',
  198.             'July' => 'juillet',
  199.             'August' => 'août',
  200.             'September' => 'septembre',
  201.             'October' => 'octobre',
  202.             'November' => 'novembre',
  203.             'December' => 'décembre'
  204.         ];
  205.         $date = clone $this->validity;
  206.         if ($modifier) {
  207.             $date $date->modify($modifier);
  208.         }
  209.         $day $date->format('d'); // Day of the month
  210.         $monthName $months[$date->format('F')]; // Full month name
  211.         $year $date->format('Y'); // Year
  212.         // Combine the formatted string
  213.         $formattedDate "$day $monthName $year";
  214.         return $formattedDate;
  215.     }
  216.     public function setValidity(\DateTimeInterface $validity): self
  217.     {
  218.         $this->validity $validity;
  219.         return $this;
  220.     }
  221.     public function isExpired(): bool
  222.     {
  223.         return $this->getValidity() < new \DateTime('now');
  224.     }
  225.     public function getValue(): ?string
  226.     {
  227.         return $this->Value;
  228.     }
  229.     public function setValue(string $Value): self
  230.     {
  231.         $this->Value $Value;
  232.         return $this;
  233.     }
  234.     public function getUsed(): ?bool
  235.     {
  236.         return $this->used;
  237.     }
  238.     public function setUsed(bool $used): self
  239.     {
  240.         $this->used $used;
  241.         return $this;
  242.     }
  243.     public function getMaxUsed(): ?int
  244.     {
  245.         return $this->max_used;
  246.     }
  247.     public function setMaxUsed(?int $max_used): self
  248.     {
  249.         $this->max_used $max_used;
  250.         return $this;
  251.     }
  252.     public function getCountUsed(): ?int
  253.     {
  254.         return $this->count_used;
  255.     }
  256.     public function setCountUsed(?int $count_used): self
  257.     {
  258.         $this->count_used $count_used;
  259.         return $this;
  260.     }
  261.     public function getServices()
  262.     {
  263.         if($this->services) {
  264.             return json_decode($this->services);
  265.         } else {
  266.             return [];
  267.         }
  268.     }
  269.     public function setServices($services): self
  270.     {
  271.         $this->services $services;
  272.         return $this;
  273.     }
  274.     public function getComment(): ?string
  275.     {
  276.         return $this->comment;
  277.     }
  278.     public function setComment(?string $comment): self
  279.     {
  280.         $this->comment $comment;
  281.         return $this;
  282.     }
  283.     public function getTemplateCarteCadeau(): TemplateCarteCadeau
  284.     {
  285.         return $this->templateCarteCadeau;
  286.     }
  287.     public function setTemplateCarteCadeau(TemplateCarteCadeau $templateCarteCadeau): self
  288.     {
  289.         $this->templateCarteCadeau $templateCarteCadeau;
  290.         return $this;
  291.     }
  292.     public function getTokens(): PersistentCollection
  293.     {
  294.         $this->token->initialize();
  295.         $iterator $this->token->getIterator();
  296.         $iterator->uasort(function ($a$b) {
  297.             return $b->getId() <=> $a->getId();
  298.         });
  299.         return $this->token;
  300.     }
  301.     public function getToken(): Token|null
  302.     {
  303.         if (!$this->token) {
  304.             return null;
  305.         }
  306.         if ($this->token->isEmpty()) {
  307.             return null;
  308.         }
  309.         // Get the criteria to sort by creation date if it exists, otherwise by ID
  310.         $criteria Criteria::create()
  311.             ->orderBy(['created' => 'ASC'])
  312.             ->setMaxResults(1);
  313.         return $this->token->matching($criteria)->first() ?: $this->token->first();
  314.     }
  315.     public function getContact(): Contact|null
  316.     {
  317.         if (!$this->getToken()) {
  318.             return null;
  319.         }
  320.         $contact $this->getToken()->getContact();
  321.         if (!$contact) {
  322.             foreach($this->getTokens() as $token) {
  323.                 if ($token->getContact()) {
  324.                     $contact $token->getContact();
  325.                     break;
  326.                 }
  327.             }
  328.         }
  329.         return $contact;
  330.     }
  331.     public function setToken(?Token $token): self
  332.     {
  333.         // unset the owning side of the relation if necessary
  334.         if ($token === null && $this->token !== null) {
  335.             $this->token->setCodePromo(null);
  336.         }
  337.         // set the owning side of the relation if necessary
  338.         if ($token !== null && $token->getCodePromo() !== $this) {
  339.             $token->setCodePromo($this);
  340.         }
  341.         $this->token $token;
  342.         return $this;
  343.     }
  344.     public function isPhysicalCard(): ?bool
  345.     {
  346.         return $this->physicalCard;
  347.     }
  348.     public function setPhysicalCard(?bool $physicalCard): self
  349.     {
  350.         $this->physicalCard $physicalCard;
  351.         return $this;
  352.     }
  353.     public function getDeliveryAddress(): ?DeliveryAddress
  354.     {
  355.         return $this->deliveryAddress;
  356.     }
  357.     public function setDeliveryAddress(?DeliveryAddress $deliveryAddress): self
  358.     {
  359.         $this->deliveryAddress $deliveryAddress;
  360.         return $this;
  361.     }
  362.     public function getResteAPayer(): ?float
  363.     {
  364.         return $this->resteAPayer ?? 0;
  365.     }
  366.     public function setResteAPayer(?float $resteAPayer): self
  367.     {
  368.         $this->resteAPayer $resteAPayer;
  369.         return $this;
  370.     }
  371.     public function getCreatedFromReservation(): ?Reservation
  372.     {
  373.         return $this->createdFromReservation;
  374.     }
  375.     public function setCreatedFromReservation(?Reservation $createdFromReservation): self
  376.     {
  377.         $this->createdFromReservation $createdFromReservation;
  378.         return $this;
  379.     }
  380.     public function getAllHistories(): array
  381.     {
  382.         $histories = new ArrayCollection();
  383.         foreach($this->getCarteCadeauHistories() as $history) {
  384.             $histories->add($history);
  385.         }
  386.         foreach($this->getToken()->getPayments() as $payment) {
  387.             if (!$payment instanceof EmptyPayment) {
  388.                 $histories->add($payment);
  389.             }
  390. //            foreach($payment->getPaymentHistories() as $history) {
  391. //                $histories->add($history->getPayment());
  392. //            }
  393.         }
  394.         // sort by createdAt
  395.         $histories $histories->toArray();
  396.         usort($histories, function($a$b) {
  397.             return $b->getCreatedAt() <=> $a->getCreatedAt();
  398.         });
  399.         return $histories;
  400.     }
  401.     /**
  402.      * @return Collection<int, CarteCadeauHistory>
  403.      */
  404.     public function getCarteCadeauHistories(): Collection
  405.     {
  406.         return $this->carteCadeauHistories;
  407.     }
  408.     public function addCarteCadeauHistory(CarteCadeauHistory $carteCadeauHistory): self
  409.     {
  410.         if (!$this->carteCadeauHistories->contains($carteCadeauHistory)) {
  411.             $this->carteCadeauHistories[] = $carteCadeauHistory;
  412.             $carteCadeauHistory->setCode($this);
  413.         }
  414.         return $this;
  415.     }
  416.     public function removeCarteCadeauHistory(CarteCadeauHistory $carteCadeauHistory): self
  417.     {
  418.         $this->carteCadeauHistories->removeElement($carteCadeauHistory);
  419.         return $this;
  420.     }
  421.     public function getCreatedAt(): ?\DateTimeInterface
  422.     {
  423.         return $this->createdAt;
  424.     }
  425.     public function setCreatedAt(?\DateTimeInterface $createdAt): self
  426.     {
  427.         $this->createdAt $createdAt;
  428.         return $this;
  429.     }
  430.     /**
  431.      * Get the current status of the carte cadeau based on business rules
  432.      * @return string The status constant from CarteCadeauStatus
  433.      */
  434.     public function getStatus(): string
  435.     {
  436.         if ($this->isExpired()) {
  437.             return CarteCadeauStatus::EXPIRE;
  438.         }
  439.         
  440.         if ($this->getUsed()) {
  441.             return CarteCadeauStatus::UTILISE;
  442.         }
  443.         
  444.         if ($this->getResteAPayer() && $this->getResteAPayer() != 0) {
  445.             return CarteCadeauStatus::INACTIF;
  446.         }
  447.         
  448.         return CarteCadeauStatus::NON_UTILISE;
  449.     }
  450.     /**
  451.      * Get the human-readable label for the current status
  452.      * @return string The French label for the status
  453.      */
  454.     public function getStatusLabel(): string
  455.     {
  456.         return CarteCadeauStatus::getLabel($this->getStatus());
  457.     }
  458.     /**
  459.      * Get the CSS class for the current status
  460.      * @return string The CSS class name for styling
  461.      */
  462.     public function getStatusCssClass(): string
  463.     {
  464.         return CarteCadeauStatus::getCssStatusClass($this->getStatus());
  465.     }
  466. }