src/Entity/CourseOccurrence.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\VenueRoom;
  4. use Doctrine\ORM\Mapping as ORM;
  5. use JMS\Serializer\Annotation as JMS;
  6. use Doctrine\Common\Collections\Collection;
  7. use Menke\UserBundle\Entity\Client;
  8. use Menke\CommonsBundle\Entity\GenericEntity;
  9. use Doctrine\Common\Collections\ArrayCollection;
  10. /**
  11.  * @ORM\Entity(repositoryClass="App\Repository\CourseOccurrenceRepository")
  12.  * @JMS\ExclusionPolicy("all")
  13.  */
  14. class CourseOccurrence extends GenericEntity
  15. {
  16.     /**
  17.      * @ORM\ManyToOne(targetEntity="App\Entity\Venue")
  18.      * @ORM\JoinColumn(name="venueId", referencedColumnName="id")
  19.      * @JMS\Expose
  20.      * @JMS\Groups({"public"})
  21.      */
  22.     protected $venue;
  23.     /**
  24.      * @ORM\ManyToOne(targetEntity="VenueRoom")
  25.      * @ORM\JoinColumn(name="venueRoomId", referencedColumnName="id", nullable=true)
  26.      * @JMS\Expose
  27.      * @JMS\Groups({"public"})
  28.      */
  29.     protected $venueRoom;
  30.     /**
  31.      * @ORM\ManyToOne(targetEntity="Course", inversedBy="occurrences")
  32.      * @ORM\JoinColumn(name="courseId", referencedColumnName="id")
  33.      */
  34.     protected $course;
  35.     /**
  36.      * @ORM\OneToMany(targetEntity="App\Entity\CourseOccurrenceTime", mappedBy="occurrence", orphanRemoval=true, cascade={"all"})
  37.      * @ORM\OrderBy({"start" = "ASC"})
  38.      * @JMS\Expose
  39.      * @JMS\Groups({"public"})
  40.      */
  41.     protected $times;
  42.     /**
  43.      * @ORM\ManyToMany(targetEntity="App\Entity\Person", mappedBy="courses")
  44.      */
  45.     protected $customers;
  46.     /**
  47.      * @ORM\ManyToMany(targetEntity="App\Entity\Speaker")
  48.      * @JMS\Expose
  49.      * @JMS\Groups({"public"})
  50.      */
  51.     protected $speakers;
  52.     /**
  53.      * @ORM\Column(type="boolean")
  54.      */
  55.     protected $published false;
  56.     /**
  57.      * @ORM\Column(type="datetime")
  58.      * @JMS\Expose
  59.      * @JMS\Groups({"public"})
  60.      */
  61.     protected $start;
  62.     /**
  63.      * @ORM\Column(type="datetime")
  64.      * @JMS\Expose
  65.      * @JMS\Groups({"public"})
  66.      */
  67.     protected $end;
  68.     /**
  69.      * @ORM\Column(type="integer")
  70.      * @JMS\Expose
  71.      * @JMS\Groups({"public"})
  72.      */
  73.     protected $slots;
  74.     /**
  75.      * @ORM\Column(type="boolean")
  76.      * @JMS\Expose
  77.      * @JMS\Groups({"public"})
  78.      */
  79.     protected $reservationAllowed false;
  80.     /**
  81.      * @ORM\Column(type="integer")
  82.      */
  83.     protected $bookedSlots 0;
  84.     protected $pendingBookings 0;
  85.     /**
  86.      * @ORM\OneToMany(targetEntity="App\Entity\WaitItem", mappedBy="courseOccurrence")
  87.      */
  88.     protected $waitItems;
  89.     /**
  90.      * @ORM\OneToMany(targetEntity="App\Entity\OrderItem", mappedBy="courseOccurrence")
  91.      */
  92.     protected $orderItems;
  93.     public function __construct()
  94.     {
  95.         $this->times = new ArrayCollection();
  96.         $this->speakers = new ArrayCollection();
  97.         $this->waitItems = new ArrayCollection();
  98.     }
  99.     /**
  100.      * @return Venue|null
  101.      */
  102.     public function getVenue(): ?Venue
  103.     {
  104.         return $this->venue;
  105.     }
  106.     /**
  107.      * @param Venue|null $venue
  108.      * @return CourseOccurrence
  109.      */
  110.     public function setVenue(?Venue $venue): self
  111.     {
  112.         $this->venue $venue;
  113.         return $this;
  114.     }
  115.     /**
  116.      * @return VenueRoom|null
  117.      */
  118.     public function getVenueRoom(): ?VenueRoom
  119.     {
  120.         return $this->venueRoom;
  121.     }
  122.     /**
  123.      * @param VenueRoom|null $venue
  124.      * @return CourseOccurrence
  125.      */
  126.     public function setVenueRoom(?VenueRoom $venueRoom): self
  127.     {
  128.         $this->venueRoom $venueRoom;
  129.         return $this;
  130.     }
  131.     /**
  132.      * @return Course
  133.      */
  134.     public function getCourse(): ?Course
  135.     {
  136.         return $this->course;
  137.     }
  138.     /**
  139.      * @param Course $course
  140.      * @return CourseOccurrence
  141.      */
  142.     public function setCourse(?Course $course)
  143.     {
  144.         $this->course $course;
  145.         return $this;
  146.     }
  147.     /**
  148.      * @return Collection|CourseOccurrenceTime[]
  149.      */
  150.     public function getTimes(): Collection
  151.     {
  152.         return $this->times;
  153.     }
  154.     /**
  155.      * @param mixed $times
  156.      * @return CourseOccurrence
  157.      */
  158.     public function setTimes($times)
  159.     {
  160.         $this->times $times;
  161.         return $this;
  162.     }
  163.     /**
  164.      * @param CourseOccurrenceTime $time
  165.      * @return CourseOccurrence
  166.      */
  167.     public function addTime(CourseOccurrenceTime $time): self
  168.     {
  169.         if (!$this->times->contains($time)) {
  170.             $this->times[] = $time;
  171.             $time->setOccurrence($this);
  172.         }
  173.         return $this;
  174.     }
  175.     /**
  176.      * @param CourseOccurrenceTime $time
  177.      * @return CourseOccurrence
  178.      */
  179.     public function removeTime(CourseOccurrenceTime $time): self
  180.     {
  181.         if ($this->times->contains($time)) {
  182.             $this->times->removeElement($time);
  183.             if ($time->getOccurrence() === $this) {
  184.                 $time->setOccurrence(null);
  185.             }
  186.         }
  187.         return $this;
  188.     }
  189.     /**
  190.      * @return Collection|Speaker[]
  191.      */
  192.     public function getSpeakers(): Collection
  193.     {
  194.         return $this->speakers;
  195.     }
  196.     /**
  197.      * @param Speaker $speaker
  198.      * @return CourseOccurrence
  199.      */
  200.     public function addSpeaker(Speaker $speaker): self
  201.     {
  202.         if (!$this->speakers->contains($speaker)) {
  203.             $this->speakers[] = $speaker;
  204.         }
  205.         return $this;
  206.     }
  207.     /**
  208.      * @param Speaker $speaker
  209.      * @return CourseOccurrence
  210.      */
  211.     public function removeSpeaker(Speaker $speaker): self
  212.     {
  213.         if ($this->speakers->contains($speaker)) {
  214.             $this->speakers->removeElement($speaker);
  215.         }
  216.         return $this;
  217.     }
  218.     /**
  219.      * @return null|string
  220.      */
  221.     public function getTitle(): ?string
  222.     {
  223.         return $this->getCourse()->getTitle();
  224.     }
  225.     /**
  226.      * @return Category|null
  227.      */
  228.     public function getCategory(): ?Category
  229.     {
  230.         return $this->getCourse()->getCategory();
  231.     }
  232.     /**
  233.      * @return float|null
  234.      */
  235.     public function getPrice(): ?float
  236.     {
  237.         return $this->getCourse()->getPrice();
  238.     }
  239.     /**
  240.      * @return null|string
  241.      */
  242.     public function getFullCaption(): ?string
  243.     {
  244.         $categoryName $this->checkIfValueExists('categoryName');
  245.         $venue $this->checkIfValueExists('venue');
  246.         $venueRoom $this->checkIfValueExists('venueRoom');
  247.         if ($venue && $venueRoom) {
  248.             $place $venue ' ' $venueRoom;
  249.         } else {
  250.             $place $venue ?? $venueRoom;
  251.         }
  252.         $category = ($categoryName) ? ' Kategorie: ' $categoryName '';
  253.         return $this->getTitle() . ' (' $this->getStart()->format('d.m.Y H:i') . ') '
  254.             $place
  255.             $category;
  256.     }
  257.     private function checkIfValueExists($value)
  258.     {
  259.         try {
  260.             switch ($value) {
  261.                 case 'categoryName':
  262.                     $result =
  263.                         $this->getCourse()->getCategory()->getName();
  264.                     break;
  265.                 case 'venue':
  266.                     $result =
  267.                         $this->getVenue()->getName();
  268.                     break;
  269.                 case 'venueRoom':
  270.                     $result =
  271.                         $this->getVenueRoom()->getName();
  272.                     break;
  273.             }
  274.         } catch (\Throwable $th) {
  275.             $result '';
  276.         }
  277.         return $result;
  278.     }
  279.     /**
  280.      * @return bool|null
  281.      */
  282.     public function getPublished(): ?bool
  283.     {
  284.         return $this->published;
  285.     }
  286.     /**
  287.      * @param bool $published
  288.      * @return CourseOccurrence
  289.      */
  290.     public function setPublished(bool $published): self
  291.     {
  292.         $this->published $published;
  293.         return $this;
  294.     }
  295.     /**
  296.      * @return bool
  297.      */
  298.     public function isAvailable(): bool
  299.     {
  300.         // Check if occurrence is published
  301.         if (!$this->getPublished()) {
  302.             return false;
  303.         }
  304.         // Check if end date of course is past
  305.         $now = new \DateTime('now');
  306.         if ($this->getEnd()->format('U') < $now->format('U')) {
  307.             return false;
  308.         }
  309.         return true;
  310.     }
  311.     /**
  312.      * @return mixed
  313.      */
  314.     public function getStart()
  315.     {
  316.         return $this->start;
  317.     }
  318.     /**
  319.      * @param \DateTimeInterface $start
  320.      * @return CourseOccurrence
  321.      */
  322.     public function setStart(\DateTimeInterface $start): self
  323.     {
  324.         $this->start $start;
  325.         return $this;
  326.     }
  327.     /**
  328.      * @return mixed
  329.      */
  330.     public function getEnd()
  331.     {
  332.         return $this->end;
  333.     }
  334.     /**
  335.      * @param \DateTimeInterface $end
  336.      * @return CourseOccurrence
  337.      */
  338.     public function setEnd(\DateTimeInterface $end): self
  339.     {
  340.         $this->end $end;
  341.         return $this;
  342.     }
  343.     /**
  344.      * @return bool
  345.      */
  346.     public function hasMultipleDays(): bool
  347.     {
  348.         return $this->getStart()->format('d.m.Y') !== $this->getEnd()->format('d.m.Y');
  349.     }
  350.     /**
  351.      * @return CourseOccurrence
  352.      */
  353.     public function clone()
  354.     {
  355.         $entity = new CourseOccurrence();
  356.         $entity->setId(null);
  357.         $entity->setVenue($this->getVenue());
  358.         $entity->setStart($this->getStart());
  359.         $entity->setEnd($this->getEnd());
  360.         $entity->setSlots($this->getSlots());
  361.         foreach ($this->getSpeakers() as $speaker) {
  362.             $entity->addSpeaker($speaker);
  363.         }
  364.         foreach ($this->getTimes() as $time) {
  365.             $entity->addTime($time->clone());
  366.         }
  367.         return $entity;
  368.     }
  369.     /**
  370.      * Sets a new start date. Moves all other dates in relation to the new start date. This includes dates of related
  371.      * CourseOccurrenceTime entities.
  372.      *
  373.      * @param \DateTime $date
  374.      */
  375.     public function setDate(\DateTime $date)
  376.     {
  377.         $date->add(new \DateInterval('P1D'));
  378.         $difference $this->getStart()->diff($date);
  379.         $difference->0;
  380.         $difference->0;
  381.         $difference->0;
  382.         $this->getStart()->add($difference);
  383.         $this->getEnd()->add($difference);
  384.         foreach ($this->getTimes() as $time) {
  385.             $time->moveDate($difference);
  386.         }
  387.     }
  388.     /**
  389.      * @return Client|null
  390.      */
  391.     public function getClient(): ?Client
  392.     {
  393.         return $this->getCourse()->getClient();
  394.     }
  395.     /**
  396.      * @return null|string
  397.      */
  398.     public function getNumber()
  399.     {
  400.         return $this->getCourse()->getNumber();
  401.     }
  402.     /**
  403.      * @return null|string
  404.      */
  405.     public function getType()
  406.     {
  407.         return $this->getCourse()->getType();
  408.     }
  409.     /**
  410.      * @return Collection|CourseImage[]
  411.      */
  412.     public function getImages(): Collection
  413.     {
  414.         return $this->getCourse()->getImages();
  415.     }
  416.     /**
  417.      * @return float|null
  418.      */
  419.     public function getMaterialCost(): ?float
  420.     {
  421.         return $this->getCourse()->getMaterialCost();
  422.     }
  423.     /**
  424.      * @return int|null
  425.      */
  426.     public function getTargetAgeMin(): ?int
  427.     {
  428.         return $this->getCourse()->getTargetAgeMin();
  429.     }
  430.     /**
  431.      * @return int|null
  432.      */
  433.     public function getTargetAgeMax(): ?int
  434.     {
  435.         return $this->getCourse()->getTargetAgeMax();
  436.     }
  437.     /**
  438.      * @return bool
  439.      */
  440.     public function hasTargetAge(): bool
  441.     {
  442.         return !empty($this->getTargetAgeMin()) || !empty($this->getTargetAgeMax());
  443.     }
  444.     /**
  445.      * @return Collection|CourseText[]
  446.      */
  447.     public function getTexts(): Collection
  448.     {
  449.         return $this->getCourse()->getTexts();
  450.     }
  451.     /**
  452.      * @return null|string
  453.      */
  454.     public function getDescription(): ?string
  455.     {
  456.         return $this->getCourse()->getDescription();
  457.     }
  458.     /**
  459.      * @return int|null
  460.      */
  461.     public function getSlots(): ?int
  462.     {
  463.         return $this->slots;
  464.     }
  465.     /**
  466.      * @param int $slots
  467.      * @return CourseOccurrence
  468.      */
  469.     public function setSlots(int $slots): self
  470.     {
  471.         $this->slots $slots;
  472.         return $this;
  473.     }
  474.     /**
  475.      * @return bool|null
  476.      */
  477.     public function getReservationAllowed(): ?bool
  478.     {
  479.         return $this->reservationAllowed;
  480.     }
  481.     /**
  482.      * @return bool|null
  483.      */
  484.     public function isReservationAllowed(): ?bool
  485.     {
  486.         return $this->getReservationAllowed();
  487.     }
  488.     /**
  489.      * @param bool $reservationAllowed
  490.      * @return CourseOccurrence
  491.      */
  492.     public function setReservationAllowed(bool $reservationAllowed): self
  493.     {
  494.         $this->reservationAllowed $reservationAllowed;
  495.         return $this;
  496.     }
  497.     /**
  498.      * /**
  499.      * @JMS\Expose
  500.      * @JMS\Groups({"public"})
  501.      * @JMS\VirtualProperty()
  502.      * @JMS\Type("int")
  503.      * @return int|null
  504.      */
  505.     public function getBookedSlots(): ?int
  506.     {
  507.         $bookedSlots 0;
  508.         if ($this->getOrderItems() !== null) {
  509.             foreach ($this->getOrderItems() as $item) {
  510.                 $order $item->getOrder();
  511.                 if (!$order->isCancelled() && !$item->isMaterialCost()) {
  512.                     $bookedSlots += $item->getQuantity() - $item->getCancelledQuantity();
  513.                 }
  514.             }
  515.         }
  516.         return $bookedSlots;
  517.     }
  518.     public function getBookedSlotsDirectly(): ?int
  519.     {
  520.         return $this->bookedSlots;
  521.     }
  522.     /**
  523.      * @param int $bookedSlots
  524.      * @return CourseOccurrence
  525.      */
  526.     public function setBookedSlots(int $bookedSlots): self
  527.     {
  528.         $this->bookedSlots $bookedSlots;
  529.         return $this;
  530.     }
  531.     /**
  532.      * @return int|null
  533.      */
  534.     public function getFreeSlots(bool $directBooked false): ?int
  535.     {
  536.         if ($directBooked === true) {
  537.             return $this->getSlots() - $this->getBookedSlotsDirectly();
  538.         } else {
  539.             return $this->getSlots() - $this->getBookedSlots();
  540.         }
  541.     }
  542.     /**
  543.      * @return null|string
  544.      */
  545.     public function getReservationStatus(): ?string
  546.     {
  547.         $freeSlots $this->getFreeSlots();
  548.         if ($freeSlots 0) {
  549.             return 'Plätze frei';
  550.         } else {
  551.             if ($this->getReservationAllowed()) {
  552.                 return 'ausgebucht - Reservierung möglich';
  553.             } else {
  554.                 return 'ausgebucht';
  555.             }
  556.         }
  557.     }
  558.     /**
  559.      * @param int $quantity
  560.      * @return CourseOccurrence
  561.      */
  562.     public function bookSlots(int $quantity): self
  563.     {
  564.         $this->pendingBookings += $quantity;
  565.         return $this;
  566.     }
  567.     /**
  568.      * @param int $quantity
  569.      * @return CourseOccurrence
  570.      */
  571.     public function cancelSlots(int $quantity): self
  572.     {
  573.         $this->pendingBookings -= $quantity;
  574.         return $this;
  575.     }
  576.     /**
  577.      * Actually book pending slots
  578.      */
  579.     public function flushBooking()
  580.     {
  581.         $bookedSlots 0;
  582.         foreach ($this->getOrderItems() as $item) {
  583.             if (!$item->getCourseItem() && !$item->getOrder()->isCancelled() && !$item->isCancelled()) {
  584.                 $bookedSlots += $item->getQuantity();
  585.             }
  586.         }
  587.         $this->bookedSlots $bookedSlots;
  588.     }
  589.     /**
  590.      * @param int $numberOfBookings
  591.      * @return bool
  592.      */
  593.     public function isBookable(int $numberOfBookingsbool $directBooked false): bool
  594.     {
  595.         return $numberOfBookings <= $this->getFreeSlots($directBooked);
  596.     }
  597.     /**
  598.      * @return Collection|WaitItem[]
  599.      */
  600.     public function getWaitItems(): Collection
  601.     {
  602.         return $this->waitItems;
  603.     }
  604.     /**
  605.      * @param WaitItem $waitItem
  606.      * @return CourseOccurrence
  607.      */
  608.     public function addWaitItem(WaitItem $waitItem): self
  609.     {
  610.         if (!$this->waitItems->contains($waitItem)) {
  611.             $this->waitItems[] = $waitItem;
  612.             $waitItem->setCourseOccurrence($this);
  613.         }
  614.         return $this;
  615.     }
  616.     /**
  617.      * @param WaitItem $waitItem
  618.      * @return CourseOccurrence
  619.      */
  620.     public function removeWaitItem(WaitItem $waitItem): self
  621.     {
  622.         if ($this->waitItems->contains($waitItem)) {
  623.             $this->waitItems->removeElement($waitItem);
  624.             // set the owning side to null (unless already changed)
  625.             if ($waitItem->getCourseOccurrence() === $this) {
  626.                 $waitItem->setCourseOccurrence(null);
  627.             }
  628.         }
  629.         return $this;
  630.     }
  631.     /**
  632.      * @return int
  633.      */
  634.     public function getWaitItemCount(): int
  635.     {
  636.         return count($this->waitItems);
  637.     }
  638.     /**
  639.      * @return bool
  640.      */
  641.     public function hasWaitList(): bool
  642.     {
  643.         return $this->isReservationAllowed() && $this->getWaitItemCount() > 0;
  644.     }
  645.     /**
  646.      * @param CourseOccurrence $target
  647.      * @return CourseOccurrence
  648.      */
  649.     public function moveWaitListTo(CourseOccurrence $target): self
  650.     {
  651.         foreach ($this->getWaitItems() as $waitItem) {
  652.             $this->removeWaitItem($waitItem);
  653.             $target->addWaitItem($waitItem);
  654.         }
  655.         return $this;
  656.     }
  657.     /**
  658.      * @return array
  659.      */
  660.     public function getSpeakerNames()
  661.     {
  662.         $speakerNames = [];
  663.         foreach ($this->getSpeakers() as $speaker) {
  664.             $speakerNames[] = $speaker->getFullname();
  665.         }
  666.         return $speakerNames;
  667.     }
  668.     /**
  669.      * @return string
  670.      */
  671.     public function getCaption()
  672.     {
  673.         return $this->getTitle() . ' (' $this->getStart()->format('d.m.Y') . ')';
  674.     }
  675.     public function getKursstart()
  676.     {
  677.         return $this->getStart()->format('d.m.Y');
  678.     }
  679.     public function getKursende()
  680.     {
  681.         return $this->getEnd()->format('d.m.Y');
  682.     }
  683.     public function getTaxRate()
  684.     {
  685.         return $this->getCourse()->getTaxRate();
  686.     }
  687.     public function getKursstartendeuhrzeit()
  688.     {
  689.         return $this->getStart()->format('H:i') . ' bis ' $this->getEnd()->format('H:i') . ' Uhr';
  690.     }
  691.     /**
  692.      * @JMS\Expose
  693.      * @JMS\Groups({"public"})
  694.      * @JMS\VirtualProperty()
  695.      * @JMS\Type("int")
  696.      * @return int
  697.      */
  698.     public function getId(): ?int
  699.     {
  700.         return parent::getId();
  701.     }
  702.     /**
  703.      * @return OrderItem[]
  704.      */
  705.     public function getOrderItems()
  706.     {
  707.         return $this->orderItems;
  708.     }
  709.     /**
  710.      *
  711.      */
  712.     public function setOrderItems($orderItems)
  713.     {
  714.         $this->orderItems $orderItems;
  715.     }
  716. }