src/Entity/CalendarEvent.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Enum\CalendarEvent\Status;
  4. use App\Enum\CalendarEvent\Type;
  5. use App\Enum\Student\VirtualStatus;
  6. use App\Library\Utils\StringUtils;
  7. use App\Repository\CalendarEventRepository;
  8. use Doctrine\Common\Collections\ArrayCollection;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\ORM\Mapping as ORM;
  11. /**
  12.  * @ORM\Entity(repositoryClass=CalendarEventRepository::class)
  13.  */
  14. class CalendarEvent
  15. {
  16.     /**
  17.      * @ORM\Id
  18.      * @ORM\GeneratedValue
  19.      * @ORM\Column(type="integer")
  20.      */
  21.     private $id;
  22.     /**
  23.      * @ORM\Column(type="string", length=255)
  24.      */
  25.     private $name;
  26.     /**
  27.      * @ORM\Column(type="date")
  28.      */
  29.     private $startDate;
  30.     /**
  31.      * @ORM\Column(type="date")
  32.      */
  33.     private $endDate;
  34.     /**
  35.      * @ORM\Column(type="integer", nullable=true)
  36.      */
  37.     private $price;
  38.     /**
  39.      * @ORM\Column(type="smallint", nullable=true)
  40.      */
  41.     private $fromLevel;
  42.     /**
  43.      * @ORM\Column(type="smallint", nullable=true)
  44.      */
  45.     private $earnLevel;
  46.     /**
  47.      * @ORM\Column(type="time")
  48.      */
  49.     private $startTime;
  50.     /**
  51.      * @ORM\Column(type="time")
  52.      */
  53.     private $endTime;
  54.     /**
  55.      * @ORM\Column(type="enum", options={"values"="calendar_event_enum"})
  56.      */
  57.     private $type Type::TYPE_COURSE;
  58.     /**
  59.      * @ORM\Column(type="boolean", nullable=true)
  60.      */
  61.     private $isCandidateReviewRequired true;
  62.     /**
  63.     * @ORM\ManyToOne(targetEntity=PaymentRequisites::class)
  64.     * @ORM\JoinColumn(nullable=true)
  65.      */
  66.     private $paymentRequisites;
  67.     /**
  68.      * @ORM\Column(type="string", length=255, nullable=true)
  69.      */
  70.     private $telegramChannelUrl;
  71.     /**
  72.      * @ORM\Column(type="string", length=100, nullable=true)
  73.      */
  74.     private $telegramChannelId;
  75.     /**
  76.      * @ORM\ManyToMany(targetEntity=CalendarEvent::class)
  77.      */
  78.     private $requireCalendarEventsParticipations;
  79.     /**
  80.      * @ORM\Column(type="boolean", nullable=true)
  81.      */
  82.     private $eventDatesApproximate;
  83.     /**
  84.      * @ORM\Column(type="enum", options={"values"="calendar_event_enum", "default"="active"}))
  85.      */
  86.     private $status Status::STATUS_ACTIVE;
  87.     /**
  88.      * @ORM\ManyToMany(targetEntity=CalendarEvent::class)
  89.      * @ORM\JoinTable(name="calendar_event_deny_participations",
  90.      *       joinColumns={@ORM\JoinColumn(name="calendar_event_id", referencedColumnName="id")},
  91.      *       inverseJoinColumns={@ORM\JoinColumn(name="deny_calendar_event_id", referencedColumnName="id")}
  92.      *  )
  93.      */
  94.     private $denyCalendarEventsParticipations;
  95.     /**
  96.      * @ORM\Column(type="smallint", nullable=true)
  97.      */
  98.     private $toLevel;
  99.     /**
  100.      * @ORM\Column(nullable=true)
  101.      */
  102.     private $requireStudentStatus;
  103.     /**
  104.      * @ORM\ManyToOne(targetEntity=CalendarEvent::class, inversedBy="connectedCalendarEvents")
  105.      * @ORM\JoinColumn(nullable=true)
  106.      */
  107.     private $connectingCalendarEvent;
  108.     /**
  109.      * @ORM\OneToMany(targetEntity=CalendarEvent::class, mappedBy="connectingCalendarEvent")
  110.      */
  111.     private $connectedCalendarEvents;
  112.     /**
  113.      * @ORM\ManyToMany(targetEntity=TelegramCampaignMessage::class)
  114.      */
  115.     private $approvedCandidatesCampaignMessages;
  116.     /**
  117.      * @ORM\ManyToOne(targetEntity=CalendarEventKind::class)
  118.      */
  119.     private $kind;
  120.     public function __construct()
  121.     {
  122.         $this->startDate = new \DateTime();
  123.         $this->endDate = new \DateTime();
  124.         $this->startTime = new \DateTime('10:00:00');
  125.         $this->endTime = new \DateTime('13:00:00');
  126.         $this->requireCalendarEventsParticipations = new ArrayCollection();
  127.         $this->approvedCandidatesCampaignMessages = new ArrayCollection();
  128.         $this->denyCalendarEventsParticipations = new ArrayCollection();
  129.         $this->connectedCalendarEvents = new ArrayCollection();
  130.     }
  131.     public function __toString()
  132.     {
  133.         return $this->getNameText();
  134.     }
  135.     public function getShortInfo(): string
  136.     {
  137.         return $this->getName() . " " . ($this->getStartDate() ? $this->getStartDate()->format('d.m.Y') : "") .
  138.             ($this->getFromLevel() ? " (с " $this->getFromLevel() . " ур.)" " (все ур.)");
  139.     }
  140.     public function getText(array $options null)
  141.     {
  142.         $options array_merge([
  143.             "quotes" => false,
  144.         ], $options ?? []);
  145.         $result = ($options['quotes'] ? $this->getNameText() : $this->getName());
  146.         return $result;
  147.     }
  148.     public function getNameText(): string
  149.     {
  150.         return $this->getTypeText() . " «" $this->getName() . "»";
  151.     }
  152.     public function getOnTypeText(): string
  153.     {
  154.         $typeText null;
  155.         switch ($this->getType()) {
  156.             case Type::TYPE_COURSE:
  157.                 $typeText "курс";
  158.                 break;
  159.             case Type::TYPE_OPEN_MEETING:
  160.                 $typeText "открытую встречу";
  161.                 break;
  162.             case Type::TYPE_MEETING:
  163.                 $typeText "конференцию";
  164.                 break;
  165.             default:
  166.                 $typeText $this->getTypeText();
  167.                 break;
  168.         }
  169.         return $typeText;
  170.     }
  171.     public function getOfTypeText(): string
  172.     {
  173.         $typeText null;
  174.         switch ($this->getType()) {
  175.             case Type::TYPE_COURSE:
  176.                 $typeText "курса";
  177.                 break;
  178.                 case Type::TYPE_OPEN_MEETING:
  179.                 $typeText "открытой встречи";
  180.                 break;
  181.             case Type::TYPE_MEETING:
  182.                 $typeText "конференции";
  183.                 break;
  184.             default:
  185.                 $typeText $this->getTypeText();
  186.                 break;
  187.         }
  188.         return $typeText;
  189.     }
  190.     public function getOnNameText(): string
  191.     {
  192.         $typeText $this->getOnTypeText();
  193.         return $typeText " «" $this->getName() . "»";
  194.     }
  195.     public function getOfNameText(): string
  196.     {
  197.         $typeText $this->getOfTypeText();
  198.         return $typeText " «" $this->getName() . "»";
  199.     }
  200.     public function getId(): ?int
  201.     {
  202.         return $this->id;
  203.     }
  204.     public function getName(): ?string
  205.     {
  206.         return $this->name;
  207.     }
  208.     public function setName(string $name): self
  209.     {
  210.         $this->name $name;
  211.         return $this;
  212.     }
  213.     public function getStartDate(): ?\DateTimeInterface
  214.     {
  215.         return $this->startDate;
  216.     }
  217.     public function setStartDate(\DateTimeInterface $startDate): self
  218.     {
  219.         $this->startDate $startDate;
  220.         return $this;
  221.     }
  222.     public function getEndDate(): ?\DateTimeInterface
  223.     {
  224.         return $this->endDate;
  225.     }
  226.     public function setEndDate(\DateTimeInterface $endDate): self
  227.     {
  228.         $this->endDate $endDate;
  229.         return $this;
  230.     }
  231.     private function _getPrice($isFirstCall false): ?int
  232.     {
  233.         if ($isFirstCall) {
  234.             if (!$this->_getPrice() && $this->getConnectedCalendarEvents()->count()) {
  235.                 $isAllPricesEqual true;
  236.                 $price null;
  237.                 foreach ($this->getConnectedCalendarEvents() as $connectedEvent) {
  238.                     if ($connectedEvent->_getPrice()) {
  239.                         if ($price === null) {
  240.                             $price $connectedEvent->_getPrice();
  241.                         } elseif ($price != $connectedEvent->_getPrice()) {
  242.                             $isAllPricesEqual false;
  243.                             break;
  244.                         }
  245.                     }
  246.                 }
  247.                 if ($isAllPricesEqual) {
  248.                     return $price;
  249.                 }
  250.             }
  251.         }
  252.         return $this->price;
  253.     }
  254.     public function getPrice(): ?int
  255.     {
  256.       return $this->_getPrice(true);
  257.     }
  258.     public function setPrice(?int $price): self
  259.     {
  260.         $this->price $price;
  261.         return $this;
  262.     }
  263.     public function getFromLevel(): ?int
  264.     {
  265.         return $this->fromLevel;
  266.     }
  267.     public function getFromLevelEmoji(): string
  268.     {
  269.         $level $this->getFromLevel();
  270.         if ($level === null || $level === 0) {
  271.             return "🔢";
  272.         }
  273.         $emojiNumbers = [
  274.             '0' => '0️⃣',
  275.             '1' => '1️⃣',
  276.             '2' => '2️⃣',
  277.             '3' => '3️⃣',
  278.             '4' => '4️⃣',
  279.             '5' => '5️⃣',
  280.             '6' => '6️⃣',
  281.             '7' => '7️⃣',
  282.             '8' => '8️⃣',
  283.             '9' => '9️⃣',
  284.         ];
  285.         $levelStr = (string)$level;
  286.         return $emojiNumbers[$levelStr[0]] . ($levelStr[1] ?? '');
  287.     }
  288.     public function getFromLevelText(): string
  289.     {
  290.         if ($this->getFromLevel() === null) {
  291.             return "";
  292.         }
  293.         if ($this->getFromLevel() === 0) {
  294.             return "все ур.";
  295.         }
  296.         return "с" StringUtils::getEnding($this->getFromLevel(),
  297.                 """о""",
  298.                 "")
  299.             . " " . (string)$this->getFromLevel() . " ур.";
  300.     }
  301.     public function setFromLevel(?int $fromLevel): self
  302.     {
  303.         $this->fromLevel $fromLevel;
  304.         return $this;
  305.     }
  306.     public function getEarnLevel(): ?int
  307.     {
  308.         return $this->earnLevel;
  309.     }
  310.     public function setEarnLevel(?int $level): self
  311.     {
  312.         $this->earnLevel $level;
  313.         return $this;
  314.     }
  315.     public function getStartTime(): ?\DateTimeInterface
  316.     {
  317.         return $this->startTime;
  318.     }
  319.     public function setStartTime(\DateTimeInterface $startTime): self
  320.     {
  321.         $this->startTime $startTime;
  322.         return $this;
  323.     }
  324.     public function getEndTime(): ?\DateTimeInterface
  325.     {
  326.         return $this->endTime;
  327.     }
  328.     public function setEndTime(\DateTimeInterface $endTime): self
  329.     {
  330.         $this->endTime $endTime;
  331.         return $this;
  332.     }
  333.     public function getType()
  334.     {
  335.         return $this->type;
  336.     }
  337.     public function getTypeText(): string
  338.     {
  339.         return Type::getText($this->getType());
  340.     }
  341.     public function setType($type): self
  342.     {
  343.         $this->type $type;
  344.         return $this;
  345.     }
  346.     public function getTopic(): string
  347.     {
  348.         if ($this->type === Type::TYPE_COURSE) {
  349.             return "Курс «" $this->getName() . "»";
  350.         } elseif ($this->type === Type::TYPE_MEETING) {
  351.             return "Конференция «" $this->getName() . "»";
  352.         } elseif ($this->type === Type::TYPE_OPEN_MEETING) {
  353.             return "Открытая встреча «" $this->getName() . "»";
  354.         } else {
  355.             return $this->getTypeText() . " «" $this->getName() . "»";
  356.         }
  357.     }
  358.     public function isIsCandidateReviewRequired(): ?bool
  359.     {
  360.         return $this->isCandidateReviewRequired;
  361.     }
  362.     public function setIsCandidateReviewRequired(?bool $isCandidateReviewRequired): self
  363.     {
  364.         $this->isCandidateReviewRequired $isCandidateReviewRequired;
  365.         return $this;
  366.     }
  367.     public function getPaymentRequisites(): ?PaymentRequisites
  368.     {
  369.         return $this->paymentRequisites;
  370.     }
  371.     public function setPaymentRequisites(?PaymentRequisites $paymentRequisites): self
  372.     {
  373.         $this->paymentRequisites $paymentRequisites;
  374.         return $this;
  375.     }
  376.     public function getNameWithCode(): string
  377.     {
  378.         return "Код " $this->getPrice() . " – " $this->getShortInfo();
  379.     }
  380.     public function isFinished(): bool
  381.     {
  382.         if (!$this->getFullEndDate()) {
  383.             return true;
  384.         }
  385.         $now = new \DateTime();
  386.         return $this->getFullEndDate() < $now;
  387.     }
  388.     public function isInProgress(): bool
  389.     {
  390.         return $this->isStarted() && !$this->isFinished();
  391.     }
  392.     public function isUpcoming(): bool
  393.     {
  394.         if (!$this->getFullStartDate()) {
  395.             return false;
  396.         }
  397.         $now = new \DateTime();
  398.         return $this->getFullStartDate() > $now;
  399.     }
  400.     public function getFullStartDate(): ?\DateTime
  401.     {
  402.         $startDate $this->getStartDate();
  403.         if (!$startDate) {
  404.             return null;
  405.         }
  406.         $startTime $this->getStartTime();
  407.         if ($startTime) {
  408.             $startDate = (clone $startDate)->setTime($startTime->format('H'), $startTime->format('i'), $startTime->format('s'));
  409.         }
  410.         return $startDate;
  411.     }
  412.     public function getFullEndDate(): ?\DateTime
  413.     {
  414.         $endDate $this->getEndDate();
  415.         if (!$endDate) {
  416.             return null;
  417.         }
  418.         $endTime $this->getEndTime();
  419.         if ($endTime) {
  420.             $endDate = (clone $endDate)->setTime($endTime->format('H'), $endTime->format('i'), $endTime->format('s'));
  421.         }
  422.         return $endDate;
  423.     }
  424.     public function isStarted(int $addDaysToStartDate null): bool
  425.     {
  426.         if (!$this->getStartDate() || $this->isFinished()) {
  427.             return false;
  428.         }
  429.         $now = (new \DateTime())->setTime(000);
  430.         $startDate = (clone $this->getStartDate())->setTime(000);
  431.         if ($addDaysToStartDate) {
  432.             $startDate $startDate->modify("+$addDaysToStartDate days");
  433.         }
  434.         return $startDate <= $now;
  435.     }
  436.     public function isRegistrationOpen(): bool
  437.     {
  438.         return !$this->isStarted(-2);
  439.     }
  440.     public function getLastRegistrationDate(): ?\DateTime
  441.     {
  442.         if (!$this->getStartDate()) {
  443.             return null;
  444.         }
  445.         $lastRegistrationDate = (clone $this->getStartDate())->modify("-3 days");
  446.         $weekendDays 0;
  447.         if (in_array((int)$lastRegistrationDate->format('N'), [67])) {
  448.             $weekendDays = (int)$lastRegistrationDate->format('N') - 5;
  449.         }
  450.         if ($weekendDays 0) {
  451.             $lastRegistrationDate $lastRegistrationDate->modify("-$weekendDays days");
  452.         }
  453.         return $lastRegistrationDate;
  454.     }
  455.     public function getHoursLeftBeforeStart(): int
  456.     {
  457.         return (int)ceil((($this->getStartDate()->getTimestamp() - (new \DateTime())->getTimestamp()) / 3600));
  458.     }
  459.     public function getTelegramChannelUrl(): ?string
  460.     {
  461.         return $this->telegramChannelUrl;
  462.     }
  463.     public function setTelegramChannelUrl(?string $telegramChannelUrl): self
  464.     {
  465.         $this->telegramChannelUrl $telegramChannelUrl;
  466.         return $this;
  467.     }
  468.     public function getTelegramChannelId(): ?string
  469.     {
  470.         return $this->telegramChannelId;
  471.     }
  472.     public function setTelegramChannelId(?string $telegramChannelId): self
  473.     {
  474.         $this->telegramChannelId $telegramChannelId;
  475.         return $this;
  476.     }
  477.     /**
  478.      * @return Collection<int, self>
  479.      */
  480.     public function getRequireCalendarEventsParticipations(): Collection
  481.     {
  482.         return $this->requireCalendarEventsParticipations;
  483.     }
  484.     public function getRequireCalendarEventsParticipationsText(): string
  485.     {
  486.         $texts = [];
  487.         foreach ($this->getRequireCalendarEventsParticipations() as $event) {
  488.             $texts[] = mb_lcfirst($event->getNameText(), 'UTF-8');
  489.         }
  490.         return implode(", "$texts);
  491.     }
  492.     public function getDenyCalendarEventsParticipationsText(): string
  493.     {
  494.         $texts = [];
  495.         foreach ($this->getDenyCalendarEventsParticipations() as $event) {
  496.             $texts[] = mb_lcfirst($event->getNameText(), 'UTF-8');
  497.         }
  498.         return implode(", "$texts);
  499.     }
  500.     public function addRequireCalendarEventsParticipation(self $requireCalendarEventsParticipation): self
  501.     {
  502.         if (!$this->requireCalendarEventsParticipations->contains($requireCalendarEventsParticipation)) {
  503.             $this->requireCalendarEventsParticipations[] = $requireCalendarEventsParticipation;
  504.         }
  505.         return $this;
  506.     }
  507.     public function removeRequireCalendarEventsParticipation(self $requireCalendarEventsParticipation): self
  508.     {
  509.         $this->requireCalendarEventsParticipations->removeElement($requireCalendarEventsParticipation);
  510.         return $this;
  511.     }
  512.     public function isStudentLevelCorrespond(?Person $person): bool
  513.     {
  514.         if (!$person) {
  515.             return false;
  516.         }
  517.         $eventLevel $this->getFromLevel();
  518.         if ($eventLevel === null) {
  519.             return true;
  520.         }
  521.         if (!$person->getStudent() || $person->getStudent()->getLevel() === null) {
  522.             return false;
  523.         }
  524.         return $person->getStudent()->getLevel() >= $eventLevel;
  525.     }
  526.     public function isEventDatesApproximate(): ?bool
  527.     {
  528.         return $this->eventDatesApproximate;
  529.     }
  530.     public function setEventDatesApproximate(?bool $eventDatesApproximate): self
  531.     {
  532.         $this->eventDatesApproximate $eventDatesApproximate;
  533.         return $this;
  534.     }
  535. //    /**
  536. //     * @return Collection<int, TelegramCampaignMessage>
  537. //     */
  538. //    public function getApprovedCandidatesCampaignMessages(): Collection
  539. //    {
  540. //        return $this->approvedCandidatesCampaignMessages;
  541. //    }
  542. //
  543. //    public function addApprovedCandidatesCampaignMessage(TelegramCampaignMessage $approvedCandidatesCampaignMessage): self
  544. //    {
  545. //        if (!$this->approvedCandidatesCampaignMessages->contains($approvedCandidatesCampaignMessage)) {
  546. //            $this->approvedCandidatesCampaignMessages[] = $approvedCandidatesCampaignMessage;
  547. //        }
  548. //
  549. //        return $this;
  550. //    }
  551. //
  552. //    public function removeApprovedCandidatesCampaignMessage(TelegramCampaignMessage $approvedCandidatesCampaignMessage): self
  553. //    {
  554. //        $this->approvedCandidatesCampaignMessages->removeElement($approvedCandidatesCampaignMessage);
  555. //
  556. //        return $this;
  557. //    }
  558.     public function getStatus()
  559.     {
  560.         return $this->status;
  561.     }
  562.     public function setStatus($status): self
  563.     {
  564.         $this->status $status;
  565.         return $this;
  566.     }
  567.     public function getStatusText(): ?string
  568.     {
  569.         return Status::getText($this->getStatus());
  570.     }
  571.     public function getStatusCssClass($prefix null): ?string
  572.     {
  573.         return Status::getCssClass($this->getStatus(), $prefix);
  574.     }
  575.     /**
  576.      * @return Collection<int, self>
  577.      */
  578.     public function getDenyCalendarEventsParticipations(): Collection
  579.     {
  580.         return $this->denyCalendarEventsParticipations;
  581.     }
  582.     public function addDenyCalendarEventsParticipation(self $denyCalendarEventsParticipation): self
  583.     {
  584.         if (!$this->denyCalendarEventsParticipations->contains($denyCalendarEventsParticipation)) {
  585.             $this->denyCalendarEventsParticipations[] = $denyCalendarEventsParticipation;
  586.         }
  587.         return $this;
  588.     }
  589.     public function removeDenyCalendarEventsParticipation(self $denyCalendarEventsParticipation): self
  590.     {
  591.         $this->denyCalendarEventsParticipations->removeElement($denyCalendarEventsParticipation);
  592.         return $this;
  593.     }
  594.     public function getToLevel(): ?int
  595.     {
  596.         return $this->toLevel;
  597.     }
  598.     public function setToLevel(?int $toLevel): self
  599.     {
  600.         $this->toLevel $toLevel;
  601.         return $this;
  602.     }
  603.     public function getRequireStudentStatus()
  604.     {
  605.         return $this->requireStudentStatus;
  606.     }
  607.     public function getRequireStudentStatusText(): string
  608.     {
  609.         return VirtualStatus::getText($this->getRequireStudentStatus());
  610.     }
  611.     public function setRequireStudentStatus($requireStudentStatus): self
  612.     {
  613.         $this->requireStudentStatus $requireStudentStatus;
  614.         return $this;
  615.     }
  616.     public function getConnectingCalendarEvent(): ?self
  617.     {
  618.         return $this->connectingCalendarEvent;
  619.     }
  620.     public function setConnectingCalendarEvent(?self $connectingCalendarEvent): self
  621.     {
  622.         $this->connectingCalendarEvent $connectingCalendarEvent;
  623.         return $this;
  624.     }
  625.     /**
  626.      * @return Collection<int, self>
  627.      */
  628.     public function getConnectedCalendarEvents(): Collection
  629.     {
  630.         return $this->connectedCalendarEvents;
  631.     }
  632.     public function addConnectedCalendarEvent(self $connectedCalendarEvent): self
  633.     {
  634.         if (!$this->connectedCalendarEvents->contains($connectedCalendarEvent)) {
  635.             $this->connectedCalendarEvents[] = $connectedCalendarEvent;
  636.             $connectedCalendarEvent->setConnectingCalendarEvent($this);
  637.         }
  638.         return $this;
  639.     }
  640.     public function removeConnectedCalendarEvent(self $connectedCalendarEvent): self
  641.     {
  642.         if ($this->connectedCalendarEvents->removeElement($connectedCalendarEvent)) {
  643.             // set the owning side to null (unless already changed)
  644.             if ($connectedCalendarEvent->getConnectingCalendarEvent() === $this) {
  645.                 $connectedCalendarEvent->setConnectingCalendarEvent(null);
  646.             }
  647.         }
  648.         return $this;
  649.     }
  650.     public function getKind(): ?CalendarEventKind
  651.     {
  652.         return $this->kind;
  653.     }
  654.     public function setKind(?CalendarEventKind $kind): self
  655.     {
  656.         $this->kind $kind;
  657.         return $this;
  658.     }
  659.     public function getFinanceCategory(): ?FinanceCategory
  660.     {
  661.         $ceKind $this->getKind();
  662.         return $ceKind $ceKind->getFinanceCategory() : null;
  663.     }
  664.     public function isSameFinanceCategory(FinanceCategory $financeCategory): bool
  665.     {
  666.         $ceFinanceCategory $this->getFinanceCategory();
  667.         if (!$ceFinanceCategory) {
  668.             return false;
  669.         }
  670.         return $ceFinanceCategory->getId() === $financeCategory->getId();
  671.     }
  672. }