<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
use App\Repository\RegistrationRepository;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(
* normalizationContext={
* "groups"={"registration:read"}
* },
* denormalizationContext={
* "groups"={"registration:write"}
* },
* itemOperations={
* "get"={
* "security"="is_granted('ROLE_CLIENT')",
* "security_message"="You are not allowed to access this ressource"
* }
* },
* collectionOperations={
* "get"={
* "security"="is_granted('ROLE_CLIENT')"
* }
* }
* )
* @ApiFilter(DateFilter::class,
* properties={
* "createdAt", "event.start", "event.end"
* }
* )
* @ApiFilter(SearchFilter::class,
* strategy="exact",
* properties={
* "id", "presence", "status", "paymentStatus", "price", "priceHt", "refundAmount", "refundDate",
* "client", "client.company",
* "event", "event.company", "event.status", "event.active",
* "visioEvent"
* }
* )
* @ApiFilter(OrderFilter::class,
* properties={
* "id", "createdAt", "updatedAt", "status", "price", "paymentStatus", "presence", "refundDate",
* "event.id", "event.name", "event.start", "event.end",
* "visioEvent.start", "visioEvent.end"
* }
* )
* @ApiFilter(PropertyFilter::class,
* arguments={
* "parameterName"="fields",
* "overrideDefaultProperties"=true
* }
* )
* @ORM\Entity(repositoryClass=RegistrationRepository::class)
*/
class Registration
{
const STATUS_PENDING = 'pending'; // when the registration needs a confirmation (aka: payment most of the time)
const STATUS_PENDING_CANCELLATION = 'pending_cancellation';
const STATUS_CANCELED = 'canceled';
const STATUS_ON_WAITING_LIST = 'on_waiting_list';
const STATUS_REGISTER = 'register';
const STATUS_SURVEY_SENT = 'survey_sent';
const PAYMENT_STATUS_FREE = 'free';
const PAYMENT_STATUS_PENDING = 'pending';
const PAYMENT_STATUS_CANCELED = 'canceled';
const PAYMENT_STATUS_FAILED = 'failed';
const PAYMENT_STATUS_SUCCESS = 'success';
const PAYMENT_STATUS_REFUND_PENDING = 'pending_refund';
const PAYMENT_STATUS_REFUND = 'refund';
const STATUSES = [
self::STATUS_REGISTER,
self::STATUS_CANCELED,
self::STATUS_SURVEY_SENT,
];
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"registration:read", "registration:read:id"})
*/
private $id;
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
* @Groups({"registration:read", "registration:read:createdAt"})
*/
private $createdAt;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"registration:read", "registration:read:payment", "registration:write", "registration:write:create"})
*/
private $payment;
/**
* @ORM\Column(type="float")
* @Groups({"registration:read", "registration:read:priceHt", "registration:write"})
*/
private $priceHt = 0;
/**
* @ORM\Column(type="float")
* @Groups({"registration:read", "registration:read:price", "registration:write"})
*/
private $price = 0;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
* @Groups({"registration:read", "registration:read:status", "registration:write"})
*/
private $status = self::STATUS_REGISTER;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"registration:read", "registration:read:paymentStatus", "registration:write"})
*/
private $paymentStatus = self::PAYMENT_STATUS_FREE;
/**
* @ORM\Column(type="boolean", options={"default": "0"})
* @Groups({"registration:read", "registration:read:presence", "registration:write"})
*/
private $presence = false;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"registration:read", "registration:read:statsCode", "registration:write"})
*/
private $statsCode = "code";
/**
* @ORM\ManyToOne(targetEntity=Event::class, inversedBy="registrations")
* @Assert\NotBlank
* @Groups({"client:read"})
* @Groups({"registration:read", "registration:read:event", "registration:write", "registration:write:create"})
*/
private $event;
/**
* @ORM\ManyToOne(targetEntity=Client::class, inversedBy="registrations")
* @ORM\JoinColumn(nullable=false)
* @Assert\NotBlank
* @Groups({"registration:read", "registration:read:client", "registration:write", "registration:write:create"})
*/
private $client;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Gedmo\Timestampable(on="update")
* @Groups({"registration:read", "registration:read:updatedAt"})
*/
private $updatedAt;
/**
* @ORM\Column(type="float", nullable=true)
* @Groups({"registration:read", "registration:read:expertNote", "registration:write"})
*/
private $expertNote;
/**
* @ORM\Column(type="float", nullable=true)
* @Groups({"registration:read", "registration:read:workshopNote", "registration:write"})
*/
private $workshopNote;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"registration:read", "registration:read:updatedBy"})
*/
private $updatedBy;
/**
* @ORM\ManyToOne(targetEntity=VisioEvent::class, inversedBy="registrations")
* @Groups({"registration:read", "registration:read:visioEvent"})
*/
private $visioEvent;
/**
* @ORM\ManyToOne(targetEntity=VisioEventPromotion::class, inversedBy="registrations")
* @Groups({"registration:read", "registration:read:token", "registration:write"})
*/
private $token;
/**
* @ORM\Column(type="float", nullable=true)
* @Groups({"registration:read", "registration:read:refundAmount", "registration:write"})
*/
private $refundAmount;
/**
* @ORM\Column(type="datetime", nullable=true)
* @Groups({"registration:read", "registration:read:refundDate", "registration:write"})
*/
private $refundDate;
public function __construct() {
$this->createdAt = new \DateTime();
$this->updatedAt = new \DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getCreatedAt(): ?\DateTime
{
return $this->createdAt;
}
public function setCreatedAt(\DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getPayment(): ?string
{
return $this->payment;
}
public function setPayment(?string $payment): self
{
$this->payment = $payment;
return $this;
}
public function getPriceHt(): ?float
{
return $this->priceHt;
}
public function setPriceHt(float $priceHt): self
{
$this->priceHt = $priceHt;
return $this;
}
public function getPrice(): ?float
{
return $this->price;
}
public function setPrice(float $price): self
{
$this->price = $price;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getPaymentStatus(): ?string
{
return $this->paymentStatus;
}
public function setPaymentStatus(?string $paymentStatus): self
{
$this->paymentStatus = $paymentStatus;
return $this;
}
public function getPresence(): ?bool
{
return $this->presence;
}
public function isPresence(): ?bool
{
return $this->presence;
}
public function setPresence(bool $presence): self
{
$this->presence = $presence;
return $this;
}
public function getStatsCode(): ?string
{
return $this->statsCode;
}
public function setStatsCode(string $statsCode): self
{
$this->statsCode = $statsCode;
return $this;
}
public function getEvent(): ?Event
{
return $this->event;
}
public function setEvent(?Event $event): self
{
$this->event = $event;
return $this;
}
public function getClient(): ?Client
{
return $this->client;
}
public function setClient(?Client $client): self
{
$this->client = $client;
return $this;
}
public function getUpdatedAt(): ?\DateTime
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTime $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return bool
*/
public function isRegistered(): bool
{
return in_array($this->getStatus(), [self::STATUS_SURVEY_SENT, self::STATUS_REGISTER]);
}
/**
* @return bool
*/
public function isRegister(): bool
{
return ($this->status == self::STATUS_REGISTER);
}
public function isPresent(): bool
{
return $this->presence;
}
public function isSurveySent(): bool
{
return ($this->status == self::STATUS_SURVEY_SENT);
}
public function getCancelLimit()
{
if ($this->getEvent()->getCancellationParameters() instanceof CancellationParameters) {
return $this->getEvent()->getCancellationParameters()->getLimitB();
}
return null;
}
public function isAnnulable(): bool
{
$params = $this->getEvent()->getCancellationParameters();
if ($params instanceof CancellationParameters && $params->getLimitB() > 0){
$date = new \DateTime();
$hours = abs($this->getEvent()->getStart()->getTimestamp() - $date->getTimestamp()) / (60 * 60);
if ($hours <= $params->getLimitB()){
return false;
}
}
return true;
}
public function getExpertNote(): ?float
{
return $this->expertNote;
}
public function setExpertNote(?float $expertNote): self
{
$this->expertNote = $expertNote;
return $this;
}
public function getWorkshopNote(): ?float
{
return $this->workshopNote;
}
public function setWorkshopNote(?float $workshopNote): self
{
$this->workshopNote = $workshopNote;
return $this;
}
public function getUpdatedBy(): ?string
{
return $this->updatedBy;
}
public function setUpdatedBy(?string $updatedBy): self
{
$this->updatedBy = $updatedBy;
return $this;
}
public function getVisioEvent(): ?VisioEvent
{
return $this->visioEvent;
}
public function setVisioEvent(?VisioEvent $visioEvent): self
{
$this->visioEvent = $visioEvent;
return $this;
}
public function isVisioValid(): bool
{
return (in_array($this->status, [
self::STATUS_PENDING,
self::STATUS_REGISTER,
self::STATUS_SURVEY_SENT,
self::STATUS_PENDING_CANCELLATION,
]));
}
public function getToken(): ?VisioEventPromotion
{
return $this->token;
}
public function setToken(?VisioEventPromotion $token): self
{
$this->token = $token;
return $this;
}
public function getRefundAmount(): ?float
{
return $this->refundAmount;
}
public function setRefundAmount(?float $refundAmount): self
{
$this->refundAmount = $refundAmount;
return $this;
}
public function getRefundDate(): ?\DateTimeInterface
{
return $this->refundDate;
}
public function setRefundDate(?\DateTimeInterface $refundDate): self
{
$this->refundDate = $refundDate;
return $this;
}
/**
* Permet de savoir si son incription est sur liste d'attente
* Status = STATUS_PENDING
* PaymentStatus = PAYMENT_STATUS_FREE
* Payment = NULL
*
* @return bool
*/
public function isOnWaitingList(): bool
{
return ($this->status === $this::STATUS_ON_WAITING_LIST);
}
/**
* Permet de savoir si la Registration est "en attente de paiement"
* @return bool
*/
public function isPendingPayment(): bool
{
return ($this->paymentStatus === $this::PAYMENT_STATUS_PENDING);
}
/**
* Permet de savoir si la Registration est "annulé"
* @return bool
*/
public function isCanceled(): bool
{
return ($this->status === $this::STATUS_CANCELED);
}
/**
* Permet de savoir si la Registration est "en attente d'annulation"
* @return bool
*/
public function isPendingCancellation(): bool
{
return ($this->status === $this::STATUS_PENDING_CANCELLATION);
}
/**
* Permet de savoir si une inscription est valide
*/
public function isValid(): bool
{
return ($this->status === $this::STATUS_REGISTER
&& ($this->paymentStatus === $this::PAYMENT_STATUS_FREE || $this->paymentStatus === $this::PAYMENT_STATUS_SUCCESS)
);
}
/**
* Permet de savoir si une inscription est gratuite
*/
public function isFree(): bool
{
return ($this->paymentStatus === $this::PAYMENT_STATUS_FREE);
}
}