<?php
namespace App\Entity;
use App\Entity\CustomExtra;
use App\Entity\History\Privatisation\PrivatisationHistory;
use App\Entity\Payment\AbstractPayment;
use App\Entity\Payment\CarteCadeauPayment;
use App\Entity\Payment\EmptyPayment;
use App\Repository\PrivatisationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Enum\PrivatisationStatus;
/**
* @ORM\Entity(repositoryClass=PrivatisationRepository::class)
*/
class Privatisation implements InterfaceReservation
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $nbParticipants;
/**
* @ORM\Column(type="datetime_immutable")
*/
private $date;
/**
* @ORM\ManyToOne(targetEntity=Contact::class, inversedBy="privatisations")
* @ORM\JoinColumn(nullable=false)
*/
private $contact;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $client_commentary;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $comment;
/**
* @ORM\OneToMany(targetEntity=ExtraReservation::class, mappedBy="privatisation", orphanRemoval=true, cascade={"persist"})
*/
private $extraReservations;
/**
* @ORM\OneToMany(targetEntity=CustomExtra::class, mappedBy="privatisation", orphanRemoval=true, cascade={"persist", "remove"})
*/
private $customExtras;
/**
* @ORM\Column(type="string", length=255)
*/
private $offer;
/**
* @ORM\Column(type="boolean")
*/
private $checkedCGV;
/**
* @ORM\OneToMany(targetEntity="App\Entity\History\Privatisation\PrivatisationHistory", mappedBy="privatisation", cascade={"remove"})
*/
private $privatisationHistories;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $resteAPayer;
/**
* @ORM\OneToMany(targetEntity=AbstractPayment::class, mappedBy="privatisation")
*/
private $abstractPayments;
/**
* @ORM\Column(type="string", length=50)
*/
private string $status;
public function __construct()
{
$this->extraReservations = new ArrayCollection();
$this->customExtras = new ArrayCollection();
$this->privatisationHistories = new ArrayCollection();
$this->abstractPayments = new ArrayCollection();
// Set default status
$this->status = PrivatisationStatus::PendingValidation->value;
}
public function getId(): ?int
{
return $this->id;
}
public function getNbParticipants(): ?int
{
return $this->nbParticipants;
}
public function setNbParticipants(int $nbParticipants): self
{
$this->nbParticipants = $nbParticipants;
return $this;
}
public function getDate(): ?\DateTimeImmutable
{
return $this->date;
}
public function setDate(\DateTimeImmutable $date): self
{
$this->date = $date;
return $this;
}
public function getContact(): ?Contact
{
return $this->contact;
}
public function setContact(?Contact $contact): self
{
$this->contact = $contact;
return $this;
}
public function getClientCommentary(): ?string
{
return $this->client_commentary;
}
public function setClientCommentary(?string $client_commentary): self
{
$this->client_commentary = $client_commentary;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
/**
* @return Collection<int, ExtraReservation>
*/
public function getExtraReservations(): Collection
{
return $this->extraReservations;
}
/**
* @return Collection<int, ExtraReservation>
*/
public function getActiveExtraReservations(): Collection
{
return $this->extraReservations->filter(function(ExtraReservation $extraReservation) {
return !$extraReservation->isEmpty();
});
}
public function addExtraReservation(ExtraReservation $extraReservation): self
{
if (!$this->extraReservations->contains($extraReservation)) {
$this->extraReservations[] = $extraReservation;
$extraReservation->setPrivatisation($this);
}
return $this;
}
public function removeExtraReservation(ExtraReservation $extraReservation): self
{
if ($this->extraReservations->removeElement($extraReservation)) {
// set the owning side to null (unless already changed)
if ($extraReservation->getPrivatisation() === $this) {
$extraReservation->setPrivatisation(null);
}
}
return $this;
}
/**
* @return Collection<int, CustomExtra>
*/
public function getCustomExtras(): Collection
{
return $this->customExtras;
}
public function addCustomExtra(CustomExtra $customExtra): self
{
if (!$this->customExtras->contains($customExtra)) {
$this->customExtras[] = $customExtra;
$customExtra->setPrivatisation($this);
}
return $this;
}
public function removeCustomExtra(CustomExtra $customExtra): self
{
if ($this->customExtras->removeElement($customExtra)) {
if ($customExtra->getPrivatisation() === $this) {
$customExtra->setPrivatisation(null);
}
}
return $this;
}
public function getOffer(): ?string
{
return $this->offer;
}
public function setOffer(string $offer): self
{
$this->offer = $offer;
return $this;
}
public function isCheckedCGV(): ?bool
{
return $this->checkedCGV;
}
public function setCheckedCGV(bool $checkedCGV): self
{
$this->checkedCGV = $checkedCGV;
return $this;
}
/**
* @return Collection<int, \App\Entity\History\Privatisation\PrivatisationHistory>
*/
public function getPrivatisationHistories(): Collection
{
return $this->privatisationHistories;
}
public function addPrivatisationHistory(\App\Entity\History\Privatisation\PrivatisationHistory $privatisationHistory): self
{
if (!$this->privatisationHistories->contains($privatisationHistory)) {
$this->privatisationHistories[] = $privatisationHistory;
$privatisationHistory->setPrivatisation($this);
}
return $this;
}
public function removePrivatisationHistory(\App\Entity\History\Privatisation\PrivatisationHistory $privatisationHistory): self
{
$this->privatisationHistories->removeElement($privatisationHistory);
return $this;
}
public function getResteAPayer(): ?float
{
return $this->resteAPayer ?? 0;
}
public function setResteAPayer(?float $resteAPayer): self
{
$this->resteAPayer = $resteAPayer;
return $this;
}
/**
* @return Collection<int, AbstractPayment>
*/
public function getAbstractPayments(): Collection
{
return $this->abstractPayments;
}
public function isPaidWithCarteCadeau(): bool
{
foreach ($this->abstractPayments as $payment) {
if ($payment instanceof CarteCadeauPayment) {
return true;
}
}
return false;
}
public function getUsedCarteCadeaux(): Collection
{
$carteCadeaux = new ArrayCollection();
foreach ($this->abstractPayments as $payment) {
if ($payment instanceof CarteCadeauPayment) {
$carteCadeaux->add($payment->getCartecadeau());
}
}
return $carteCadeaux;
}
public function addAbstractPayment(AbstractPayment $abstractPayment): self
{
if (!$this->abstractPayments->contains($abstractPayment)) {
$this->abstractPayments[] = $abstractPayment;
$abstractPayment->setPrivatisation($this);
}
return $this;
}
public function removeAbstractPayment(AbstractPayment $abstractPayment): self
{
if ($this->abstractPayments->removeElement($abstractPayment)) {
// set the owning side to null (unless already changed)
if ($abstractPayment->getPrivatisation() === $this) {
$abstractPayment->setPrivatisation(null);
}
}
return $this;
}
public function getAllHistories(): array
{
$histories = new ArrayCollection();
foreach($this->getPrivatisationHistories() as $history) {
$histories->add($history);
}
foreach($this->getAbstractPayments() as $payment) {
if (!$payment instanceof EmptyPayment) {
$histories->add($payment);
}
}
// sort by createdAt
$histories = $histories->toArray();
usort($histories, function($a, $b) {
return $b->getCreatedAt() <=> $a->getCreatedAt();
});
return $histories;
}
/**
* Get only payment histories from all histories
* @return array Payment histories sorted by creation date (newest first)
*/
public function getPaymentHistories(): array
{
$paymentHistories = new ArrayCollection();
foreach($this->getAbstractPayments() as $payment) {
if (!$payment instanceof EmptyPayment) {
$paymentHistories->add($payment);
}
}
// sort by createdAt
$histories = $paymentHistories->toArray();
usort($histories, function($a, $b) {
return $b->getCreatedAt() <=> $a->getCreatedAt();
});
return $histories;
}
public function getStatus(): PrivatisationStatus
{
return PrivatisationStatus::from($this->status);
}
public function setStatus(PrivatisationStatus $status): self
{
$this->status = $status->value;
return $this;
}
/**
* Shortcut helpers
*/
public function isConfirmedStatus(): bool { return $this->status === PrivatisationStatus::Confirmed->value; }
public function isCanceledStatus(): bool { return $this->status === PrivatisationStatus::Canceled->value; }
public function isDeletedStatus(): bool { return $this->status === PrivatisationStatus::Deleted->value; }
/**
* Get the creation date from the CreatePrivatisationHistory
*
* @return \DateTime|null The creation date or null if not found
*/
public function getCreatedAt(): ?\DateTime
{
foreach ($this->privatisationHistories as $history) {
if ($history instanceof \App\Entity\History\Privatisation\CreatePrivatisationHistory) {
return $history->getCreatedAt();
}
}
return null;
}
// Legacy getters/setters for backward compatibility during migration
public function getCommentary(): ?string
{
return $this->client_commentary;
}
public function setCommentary(?string $commentary): self
{
$this->client_commentary = $commentary;
return $this;
}
public function getDuration(): ?string
{
return $this->offer;
}
public function setDuration(string $duration): self
{
$this->offer = $duration;
return $this;
}
public function getArrivalDate(): ?\DateTimeInterface
{
$date = clone $this->getDate();
return $date->modify('-15 minutes');
}
public function getDepartureDate(): ?\DateTimeInterface
{
$date = clone $this->getDate();
return $this->getOffer() == "120" ?
$date->modify('+135 minutes') : // 2h privatisation + 15 min buffer
$date->modify('+195 minutes'); // 3h privatisation + 15 min buffer
}
public function getDateFormated(): string
{
// French day and month names
$days = [
'Sunday' => 'Dimanche',
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi'
];
$months = [
'January' => 'janvier',
'February' => 'février',
'March' => 'mars',
'April' => 'avril',
'May' => 'mai',
'June' => 'juin',
'July' => 'juillet',
'August' => 'août',
'September' => 'septembre',
'October' => 'octobre',
'November' => 'novembre',
'December' => 'décembre'
];
$date = $this->getDate();
// Format components
$dayName = $days[$date->format('l')]; // Full day name
$day = $date->format('d'); // Day of the month
$monthName = $months[$date->format('F')]; // Full month name
$year = $date->format('Y'); // Year
$time = $date->format('H\h') . str_pad($date->format('i'), 2, '0', STR_PAD_LEFT);
// Combine the formatted string
$formattedDate = "$dayName $day $monthName $year à $time";
return $formattedDate;
}
}