<?php
namespace App\Entity;
use App\Enum\Candidate\Status;
use App\Repository\CandidateRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CandidateRepository::class)
*/
class Candidate
{
const CANDIDATE_FIELD_STATUS = 'candidate_status';
const CANDIDATE_FIELD_PERSON = 'candidate_person';
const CANDIDATE_FIELD_AUTHOR = 'candidate_author';
const CANDIDATE_FIELD_CALENDAR_EVENT = 'candidate_calendar_event';
const CANDIDATE_FIELD_CREATED_AT = 'candidate_created_at';
const CANDIDATE_FIELD_APPROVED_AT = 'candidate_approved_at';
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="enum", options={"values": "candidate_enum"})
*/
private $status = Status::STATUS_DRAFT;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
*/
private $author;
/**
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=true)
*/
private $person;
/**
* @ORM\ManyToOne(targetEntity=CalendarEvent::class)
*/
private $calendarEvent;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $viewerComment;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $approvedAt;
/**
* @ORM\ManyToOne(targetEntity=Image::class, cascade={"persist", "remove"})
*/
private $image;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $comment;
/**
* @ORM\Column(type="boolean", nullable=true)
*/
private $paymentDeferment;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private $selectedAuthor;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $recommendations;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private $curator;
/**
* @ORM\Column(type="datetime")
*/
private $updatedAt;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $reviewApproveComment;
/**
* @ORM\Column(type="boolean", nullable=true)
*/
private $accessByReceipt;
public function __construct()
{
$this->createdAt = new \DateTime();
$this->updatedAt = new \DateTime();
}
public function getId(): ?int
{
return $this->id;
}
public function getStatus()
{
return $this->status;
}
public function isStatusApproved(): bool
{
return $this->status === Status::STATUS_APPROVED;
}
public function getCalendarEventListedVirtualStatus(bool $hasPayments): string
{
if ($this->isStatusApproved()) {
if ($hasPayments) {
return "approved";
} else {
return "unpaid";
}
} else if ($this->isStatusLeaved()) {
return "leaved";
} else {
return "not_active";
}
}
public function getCalendarEventListedVirtualStatusText(bool $hasPayments): string
{
if ($this->isStatusApproved()) {
if ($hasPayments) {
return "Зачислен";
} else if ($this->accessByReceipt) {
return "Зачислен по квитанции";
} else {
return "Не оплачен";
}
} else if ($this->isStatusLeaved()) {
return "Выбыл с мероприятия";
} else if ($this->isStatusRefused()) {
return "Не пошел";
} else {
return "Не активен";
}
}
public function getCalendarEventListedVirtualStatusCssClass(bool $hasPayments): string
{
if ($this->isStatusApproved()) {
if ($hasPayments || $this->accessByReceipt) {
return "success";
} else {
return "light";
}
} else if ($this->isStatusLeaved()) {
return "warning";
} else {
return "danger";
}
}
public function isStatusDeclined(): bool
{
return $this->status === Status::STATUS_DECLINED;
}
public function isStatusRefused(): bool
{
return $this->status === Status::STATUS_REFUSED;
}
public function setStatus($status): self
{
if ($this->status != Status::STATUS_APPROVED &&
$this->status != Status::STATUS_REFUSED &&
$status == Status::STATUS_REFUSED) {
throw new \InvalidArgumentException("Нельзя поменять статус кандидата на Не пошел, "
. "текущий статус должен быть Принят, т.к. под статусом Не пошел подразумевается, что кандидат прошел отбор.");
}
$this->status = $status;
if ($status == Status::STATUS_APPROVED && !$this->getApprovedAt()) {
$this->setApprovedAt(new \DateTime());
}
return $this;
}
public function getAuthor(): ?User
{
// if ($this->getSelectedAuthor()) {
// return $this->getSelectedAuthor();
// }
return $this->author;
}
public function setAuthor(?User $author): self
{
$this->author = $author;
return $this;
}
public function getPerson(): ?Person
{
return $this->person;
}
public function setPerson(?Person $person): self
{
$this->person = $person;
return $this;
}
public function getCalendarEvent(): ?CalendarEvent
{
return $this->calendarEvent;
}
public function setCalendarEvent(?CalendarEvent $calendarEvent): self
{
$this->calendarEvent = $calendarEvent;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getViewerComment(): ?string
{
return $this->viewerComment;
}
public function setViewerComment(?string $viewerComment): self
{
$this->viewerComment = $viewerComment;
return $this;
}
public function getAllComments(): string
{
$comments = "";
if ($this->getComment()) {
$comments = $this->getComment();
$comments = str_ends_with($comments, '.') ? $comments : ($comments . '.');
}
if ($this->getReviewApproveComment()) {
if ($comments) {
$comments .= "\n";
}
$reviewApproveComment = $this->getReviewApproveComment();
$reviewApproveComment = str_ends_with($reviewApproveComment, '.')
? $reviewApproveComment : ($reviewApproveComment . '.');
$comments .= $reviewApproveComment;
}
return $comments;
}
public function getApprovedAt(): ?\DateTimeInterface
{
return $this->approvedAt;
}
public function setApprovedAt(?\DateTimeInterface $approvedAt): self
{
$this->approvedAt = $approvedAt;
return $this;
}
public function getImage(): ?Image
{
return $this->image;
}
public function setImage(?Image $image): self
{
$this->image = $image;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
public function addComment(string $text, bool $checkContains = true,
bool $ucfirst = false, bool $addDot = false): void
{
if ($ucfirst) {
$text = mb_ucfirst($text, 'UTF-8');
}
if ($addDot && mb_substr($text, -1, null, 'UTF-8') !== '.') {
$text .= '.';
}
$newComment = trim($this->comment ?? "");
if (!$checkContains || mb_strpos($newComment , $text, null, 'UTF-8') === false) {
$newComment = $newComment
. ($addDot && $newComment && mb_substr($newComment, -1, null, 'UTF-8') !== '.' ? '.' : '')
. ($newComment ? "\n" : "")
. $text;
$this->setComment($newComment);
}
}
public function getStatusText(): string
{
return Status::getText($this->status);
}
public function getVirtualStatusText(): string
{
if ($this->isVirtualStatusNotRequired()) {
return Status::getText(Status::STATUS_NOT_REQUIRED);
}
return Status::getText($this->status);
}
public function getCssClass(): string
{
return Status::getCssClass($this->status);
}
public function isStatusLeaved(): bool
{
return $this->status === Status::STATUS_LEAVED;
}
public function isVirtualStatusNotRequired(): bool
{
return Status::isVirtualStatusNotRequired(
$this->status,
$this->getCalendarEvent(),
$this->getPerson()
);
}
public function getVirtualCssClass(): string
{
if ($this->isVirtualStatusNotRequired()) {
return Status::getCssClass(Status::STATUS_NOT_REQUIRED);
}
return Status::getCssClass($this->status);
}
public function isPaymentDeferment(): ?bool
{
return $this->paymentDeferment;
}
public function setPaymentDeferment(?bool $paymentDeferment): self
{
$this->paymentDeferment = $paymentDeferment;
return $this;
}
public function getSelectedAuthor(): ?User
{
return $this->selectedAuthor;
}
public function setSelectedAuthor(?User $selectedAuthor): self
{
$this->selectedAuthor = $selectedAuthor;
return $this;
}
public function getRecommendations(): ?string
{
return $this->recommendations;
}
public function setRecommendations(?string $recommendations): self
{
$this->recommendations = $recommendations;
return $this;
}
public function getCurator(): ?User
{
return $this->curator;
}
public function setCurator(?User $curator): self
{
$this->curator = $curator;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
if (!$this->updatedAt) {
return $this->getCreatedAt();
}
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function isTimeToSendReviewResultMessage(): array
{
$result = [
"result" => false,
'waitMinutes' => null,
];
$minutesLeftSinceUpdate = (int)ceil((time() - $this->getUpdatedAt()->getTimestamp()) / 60);
if ($this->getCalendarEvent()->getHoursLeftBeforeStart() >= 6 &&
$minutesLeftSinceUpdate < 15
) {
$result['result'] = false;
$result['waitMinutes'] = 15 - $minutesLeftSinceUpdate;
} else {
$result['result'] = true;
}
return $result;
}
public function getReviewApproveComment(): ?string
{
return $this->reviewApproveComment;
}
public function setReviewApproveComment(?string $reviewApproveComment): self
{
$reviewApproveComment = trim($reviewApproveComment);
if (!$reviewApproveComment) {
return $this;
}
$this->reviewApproveComment = $reviewApproveComment;
return $this;
}
public function isAccessByReceipt(): ?bool
{
return $this->accessByReceipt;
}
public function setAccessByReceipt(?bool $accessByReceipt): self
{
$this->accessByReceipt = $accessByReceipt;
return $this;
}
}