- <?php
- declare(strict_types=1);
- namespace App\Entity;
- use DateTime;
- use Doctrine\Common\Collections\ArrayCollection;
- use Doctrine\Common\Collections\Collection;
- use Doctrine\ORM\Mapping as ORM;
- use Symfony\Component\Validator\Constraints as Assert;
- /**
-  * @ORM\Table(name="`order`")
-  * @ORM\Entity(repositoryClass="App\Repository\OrderRepository")
-  */
- class Order
- {
-     public const STATE_PENDING = 0;
-     public const STATE_ACCEPTED = 1;
-     public const STATE_PAID = 2;
-     public const STATE_PAYMENTPENDING = 3;
-     public const STATE_REFUNDED = 4;
-     public const STATE_CANCELED = 5;
-     public const PAYMENTMODE_CB = 0;
-     public const PAYMENTMODE_WIRE = 1;
-     public const PAYMENTMODE_OFFLINE = 2;
-     /**
-      * @ORM\Column(name="id", type="integer")
-      * @ORM\Id
-      * @ORM\GeneratedValue(strategy="AUTO")
-      */
-     private $id;
-     /**
-      * @ORM\Column(type="string", length=10, nullable=false)
-      */
-     private $reference;
-     /**
-      * @ORM\OneToOne(targetEntity="App\Entity\Payment")
-      */
-     private $payment;
-     /**
-      * @ORM\OneToOne(targetEntity="App\Entity\UserSurvey", inversedBy="order", cascade={"persist","remove"})
-      * @ORM\JoinColumn(name="user_survey_id", referencedColumnName="id", onDelete="CASCADE")
-      */
-     private $userSurvey;
-     /**
-      * @ORM\Column(type="decimal", precision=9, scale=3, nullable=false)
-      */
-     private $amount;
-     /**
-      * @ORM\Column(type="decimal", precision=9, scale=3, nullable=false)
-      */
-     private $amountNoDiscount;
-     /**
-      * @ORM\Column(type="string", length=3, nullable=false)
-      */
-     private $currency;
-     /**
-      * @ORM\Column(type="smallint", nullable=true)
-      */
-     private $paymentMode;
-     /**
-      * @ORM\Column(type="string", length=50, nullable=true)
-      */
-     private $paymentProvider;
-     /**
-      * @ORM\Column(type="string", length=50, nullable=true)
-      */
-     private $paymentStatus;
-     /**
-      * @ORM\Column(type="smallint", nullable=false)
-      */
-     private $state;
-     private $stateLabel;
-     /**
-      * @Assert\NotBlank(groups={"order_confirm"})
-      * @Assert\NotNull(groups={"order_confirm"})
-      * @ORM\Column(type="boolean", nullable=false)
-      */
-     private $isLegalNoticeValidated;
-     /**
-      * @ORM\Column(type="datetime", nullable=true)
-      */
-     private $dateAdd;
-     /**
-      * @ORM\Column(type="datetime", nullable=true)
-      */
-     private $dateUpdate;
-     /**
-      * @ORM\Column(type="datetime", nullable=true)
-      */
-     private $dateLegalNoticeValidated;
-     /**
-      * @ORM\Column(type="datetime", nullable=true)
-      */
-     private $datePayment;
-     /**
-      * @ORM\Column(type="datetime", nullable=true)
-      */
-     private $dateCancel;
-     /**
-      * @ORM\Column(type="boolean", nullable=true)
-      */
-     private $isCompletedOnce;
-     /**
-      * @ORM\ManyToMany(targetEntity="App\Entity\Discount", inversedBy="orders",cascade={"persist"})
-      * @ORM\JoinColumn(nullable=true)
-      */
-     private $discounts;
-     /**
-      * @ORM\Column(type="decimal", precision=9, scale=3, nullable=false)
-      */
-     private $discountAmount;
-     /**
-      * @ORM\Column(type="integer", nullable=true)
-      */
-     private $bexioInvoiceId;
-     /**
-      * @ORM\OneToMany(targetEntity=OrderSupplement::class, mappedBy="relatedOrder", orphanRemoval=true,cascade={"persist"})
-      */
-     private $orderSupplements;
-     /**
-      * @ORM\Column(type="integer", nullable=true)
-      */
-     private $affiliationCount;
-     /**
-      * @ORM\Column(type="boolean", nullable=true)
-      */
-     private $bexioIsPaid;
-     /**
-      * Order constructor.
-      *
-      * @throws \Exception
-      */
-     public function __construct(float      $amount,
-                                 UserSurvey $userSurvey,
-                                 string     $currency = 'CHF',
-                                 bool       $isLegalNoticeValidated = false,
-                                 int        $state = Order::STATE_PENDING)
-     {
-         $this->reference = substr(md5($userSurvey->getId() . time()), 0, 10);
-         $this->amount = $amount;
-         $this->amountNoDiscount = $amount;
-         $this->userSurvey = $userSurvey;
-         $this->currency = $currency;
-         $this->isLegalNoticeValidated = $isLegalNoticeValidated;
-         $this->state = $state;
-         $this->dateAdd = new DateTime();
-         $this->dateUpdate = new DateTime();
-         $this->discounts = new ArrayCollection();
-         $this->discountAmount = 0;
-         $this->orderSupplements = new ArrayCollection();
-     }
-     public function getId(): ?int
-     {
-         return $this->id;
-     }
-     public function setId(?int $id): Order
-     {
-         $this->id = $id;
-         return $this;
-     }
-     public function getAmount(): float
-     {
-         return (float)$this->amount;
-     }
-     public function setAmount(float $amount): Order
-     {
-         $this->amount = $amount;
-         if (!is_null($this->userSurvey)) {
-             $this->userSurvey->setPrice($amount);
-         }
-         return $this;
-     }
-     public function getCurrency(): string
-     {
-         return $this->currency;
-     }
-     public function setCurrency(string $currency): Order
-     {
-         $this->currency = $currency;
-         return $this;
-     }
-     public function isLegalNoticeValidated(): bool
-     {
-         return $this->isLegalNoticeValidated;
-     }
-     public function getIsLegalNoticeValidated(): ?bool
-     {
-         return $this->isLegalNoticeValidated;
-     }
-     public function setIsLegalNoticeValidated(bool $isLegalNoticeValidated): Order
-     {
-         $this->isLegalNoticeValidated = $isLegalNoticeValidated;
-         return $this;
-     }
-     public function getDateLegalNoticeValidated(): DateTime
-     {
-         return $this->dateLegalNoticeValidated;
-     }
-     public function setDateLegalNoticeValidated(DateTime $dateLegalNoticeValidated): Order
-     {
-         $this->dateLegalNoticeValidated = $dateLegalNoticeValidated;
-         return $this;
-     }
-     public function getDatePayment(): ?DateTime
-     {
-         return $this->datePayment;
-     }
-     public function setDatePayment(?DateTime $datePayment): Order
-     {
-         $this->datePayment = $datePayment;
-         return $this;
-     }
-     public function getDateCancel(): ?DateTime
-     {
-         return $this->dateCancel;
-     }
-     public function setDateCancel(?DateTime $dateCancel): Order
-     {
-         $this->dateCancel = $dateCancel;
-         return $this;
-     }
-     public function getStateLabel(): string
-     {
-         switch ($this->getState()) {
-             case Order::STATE_PAID === $this->getState():
-                 $this->setStateLabel('Payée');
-                 break;
-             case Order::STATE_PAYMENTPENDING === $this->getState():
-                 $this->setStateLabel('Paiement en cours');
-                 break;
-             case Order::STATE_ACCEPTED === $this->getState():
-                 $this->setStateLabel('Acceptée');
-                 break;
-             case Order::STATE_PENDING === $this->getState():
-                 $this->setStateLabel('En attente de d\'acceptation');
-                 break;
-             case Order::STATE_REFUNDED === $this->getState():
-                 $this->setStateLabel('Remboursée');
-                 break;
-             case Order::STATE_CANCELED === $this->getState():
-                 $this->setStateLabel('Annulée');
-                 break;
-             default:
-                 $this->setStateLabel('Commande créée');
-         }
-         return $this->stateLabel;
-     }
-     public function getState(): int
-     {
-         return $this->state;
-     }
-     public function setState(int $state): Order
-     {
-         $this->state = $state;
-         return $this;
-     }
-     private function setStateLabel(string $stateLabel): Order
-     {
-         $this->stateLabel = $stateLabel;
-         return $this;
-     }
-     public function getDateAdd(): ?DateTime
-     {
-         return $this->dateAdd;
-     }
-     public function setDateAdd(?DateTime $dateAdd): Order
-     {
-         $this->dateAdd = $dateAdd;
-         return $this;
-     }
-     public function getDateUpdate(): ?DateTime
-     {
-         return $this->dateUpdate;
-     }
-     public function setDateUpdate(?DateTime $dateUpdate): Order
-     {
-         $this->dateUpdate = $dateUpdate;
-         return $this;
-     }
-     public function getPayment(): ?Payment
-     {
-         return $this->payment;
-     }
-     public function setPayment(?Payment $payment): self
-     {
-         $this->payment = $payment;
-         return $this;
-     }
-     public function getReference(): ?string
-     {
-         return $this->reference;
-     }
-     public function setReference(string $reference): self
-     {
-         $this->reference = $reference;
-         return $this;
-     }
-     public function getPaymentMode(): ?int
-     {
-         return $this->paymentMode;
-     }
-     public function setPaymentMode(?int $paymentMode): self
-     {
-         $this->paymentMode = $paymentMode;
-         return $this;
-     }
-     public function getPaymentProvider(): ?string
-     {
-         return $this->paymentProvider;
-     }
-     public function setPaymentProvider(?string $paymentProvider): self
-     {
-         $this->paymentProvider = $paymentProvider;
-         return $this;
-     }
-     public function isPaid(): ?bool
-     {
-         if (2 == $this->state) {
-             return true;
-         }
-         return false;
-     }
-     public function isPaymentPending(): ?bool
-     {
-         if ($this->state < 2) {
-             return true;
-         }
-         return false;
-     }
-     public function isPaymentProcessing(): ?bool
-     {
-         if (3 == $this->state) {
-             return true;
-         }
-         return false;
-     }
-     public function getPaymentStatus(): ?string
-     {
-         return $this->paymentStatus;
-     }
-     /**
-      * Preferable d'utilisé UserSurvey setPaymentStatus,.
-      */
-     public function setPaymentStatus(?string $paymentStatus): self
-     {
-         if ('payedout' == $paymentStatus || 'captured' == $paymentStatus) {
-             $this->setState(Order::STATE_PAID);
-         } elseif ('canceled' == $paymentStatus) {
-             $this->setState(Order::STATE_CANCELED);
-         } elseif ('pending' == $paymentStatus) {
-             $this->setState(Order::STATE_PAYMENTPENDING);
-         }
-         $this->paymentStatus = $paymentStatus;
-         return $this;
-     }
-     public function getIsCompletedOnce(): ?bool
-     {
-         return $this->isCompletedOnce;
-     }
-     public function setIsCompletedOnce(?bool $isCompletedOnce): self
-     {
-         $this->isCompletedOnce = $isCompletedOnce;
-         return $this;
-     }
-     public function addDiscount(Discount $discount): self
-     {
-         if (!$this->discounts->contains($discount)) {
-             $this->discounts[] = $discount;
-         }
-         return $this;
-     }
-     public function removeDiscount(Discount $discount): self
-     {
-         if ($this->discounts->contains($discount)) {
-             $this->discounts->removeElement($discount);
-         }
-         return $this;
-     }
-     public function getAmountNoDiscount(): ?float
-     {
-         return (float)$this->amountNoDiscount;
-     }
-     public function setAmountNoDiscount(float $amountNoDiscount): self
-     {
-         $this->amountNoDiscount = $amountNoDiscount;
-         return $this;
-     }
-     public function getBexioInvoiceId(): ?int
-     {
-         return $this->bexioInvoiceId;
-     }
-     public function setBexioInvoiceId(int $bexioInvoiceId): self
-     {
-         $this->bexioInvoiceId = $bexioInvoiceId;
-         return $this;
-     }
-     public function updateAmounts($price): void
-     {
-         $totalSupplements = 0;
-         $totalReductions = 0;
-         $priceModified = $price;
-         /*
-          * Les supplements sont appliqués sur le prix de base
-          */
-         foreach ($this->getOrderSupplements() as $supplement) {
-             $supplementAmount = $supplement->calculateAmount($price);
-             $totalSupplements += $supplementAmount;
-             $priceModified += $supplementAmount;
-         }
-         /*
-          * Les réductions sont appliquées sur le prix avec les supplements
-          */
-         foreach ($this->getDiscounts() as $discount) {
-             $reduction = 0;
-             if ('AFFILIATION' == $discount->getType() && $discount->getUser() == $this->getUserSurvey()->getUser()) {
-                 // parrainage
-                 if ($this->getAffiliationCount() > 0) {
-                     for ($i = 1; $i <= $this->getAffiliationCount(); ++$i) {
-                         if ($priceModified > 0) {
-                             $reduction += $discount->calculateAmount($priceModified);
-                         }
-                     }
-                 }
-             } else {
-                 // dans tous les autres cas
-                 $reduction = $discount->calculateAmount($priceModified);
-             }
-             $priceModified -= $reduction;
-             $totalReductions += $reduction;
-         }
-         if ($totalReductions > $price) {
-             $totalReductions = $price;
-         }
-         /*
-          * Ensuite, on ajoute les supplement et on déduit les réductions
-          */
-         $this->setAmountNoDiscount($price);
-         $this->setDiscountAmount($totalReductions);
-         $this->setAmount(round($price + $totalSupplements - $totalReductions, 2));
-     }
-     /**
-      * @return Collection<int, OrderSupplement>
-      */
-     public function getOrderSupplements(): Collection
-     {
-         return $this->orderSupplements;
-     }
-     /**
-      * @return Collection|Discount[]
-      */
-     public function getDiscounts(): Collection
-     {
-         return $this->discounts;
-     }
-     public function getUserSurvey(): UserSurvey
-     {
-         return $this->userSurvey;
-     }
-     public function setUserSurvey(UserSurvey $userSurvey): Order
-     {
-         $this->userSurvey = $userSurvey;
-         return $this;
-     }
-     public function getAffiliationCount(): ?int
-     {
-         return $this->affiliationCount;
-     }
-     public function setAffiliationCount(?int $affiliationCount): self
-     {
-         $this->affiliationCount = $affiliationCount;
-         return $this;
-     }
-     public function getDiscountAmount(): float
-     {
-         return (float)$this->discountAmount;
-     }
-     public function setDiscountAmount(float $discountAmount): self
-     {
-         $this->discountAmount = $discountAmount;
-         return $this;
-     }
-     public function addOrderSupplement(OrderSupplement $orderSupplement): self
-     {
-         if (!$this->orderSupplements->contains($orderSupplement)) {
-             $this->orderSupplements[] = $orderSupplement;
-             $orderSupplement->setRelatedOrder($this);
-         }
-         return $this;
-     }
-     public function removeOrderSupplement(OrderSupplement $orderSupplement): self
-     {
-         if ($this->orderSupplements->removeElement($orderSupplement)) {
-             // set the owning side to null (unless already changed)
-             if ($orderSupplement->getRelatedOrder() === $this) {
-                 $orderSupplement->setRelatedOrder(null);
-             }
-         }
-         return $this;
-     }
-     public function hasFidelity(): bool
-     {
-         foreach ($this->getDiscounts() as $discount) {
-             if ('FIDELITY' == $discount->getType()) {
-                 return true;
-             }
-         }
-         return false;
-     }
-     public function hasAffiliation(): bool
-     {
-         foreach ($this->getDiscounts() as $discount) {
-             if ('AFFILIATION' == $discount->getType()) {
-                 return true;
-             }
-         }
-         return false;
-     }
-     public function isBexioIsPaid(): ?bool
-     {
-         return $this->bexioIsPaid;
-     }
-     public function setBexioIsPaid(?bool $bexioIsPaid): self
-     {
-         $this->bexioIsPaid = $bexioIsPaid;
-         return $this;
-     }
- }
-