reservations = new ArrayCollection(); $this->attributes = new ArrayCollection(); } /** * @param SummitRoomReservation $reservation * @return $this * @throws ValidationException */ public function addReservation(SummitRoomReservation $reservation){ $criteria = Criteria::create(); $start_date = $reservation->getStartDatetime(); $end_date = $reservation->getEndDatetime(); $criteria ->where(Criteria::expr()->eq('start_datetime', $start_date)) ->andWhere(Criteria::expr()->eq('end_datetime',$end_date)) ->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus])); if($this->reservations->matching($criteria)->count() > 0) throw new ValidationException(sprintf("reservation overlaps an existent reservation")); $criteria ->where(Criteria::expr()->lte('start_datetime', $end_date)) ->andWhere(Criteria::expr()->gte('end_datetime', $start_date)) ->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus])); if($this->reservations->matching($criteria)->count() > 0) throw new ValidationException(sprintf("reservation overlaps an existent reservation")); $summit = $this->summit; $local_start_date = $summit->convertDateFromUTC2TimeZone($start_date); $local_end_date = $summit->convertDateFromUTC2TimeZone($end_date); $start_time = $summit->getMeetingRoomBookingStartTime(); $end_time = $summit->getMeetingRoomBookingEndTime(); if(!$summit->isTimeFrameInsideSummitDuration($local_start_date, $local_end_date)) throw new ValidationException("requested reservation period does not belong to summit period"); $local_start_time = new \DateTime("now", $this->summit->getTimeZone()); $local_start_time->setTime( intval($start_time->format("H")), intval($start_time->format("i")), intval($start_time->format("s")) ); $local_end_time = new \DateTime("now", $this->summit->getTimeZone()); $local_end_time->setTime( intval($end_time->format("H")), intval($end_time->format("i")), intval($end_time->format("s")) ); $local_start_time->setDate ( intval($start_date->format("Y")), intval($start_date->format("m")), intval($start_date->format("d")) ); $local_end_time->setDate ( intval($start_date->format("Y")), intval($start_date->format("m")), intval($start_date->format("d")) ); if(!($local_start_time <= $local_start_date && $local_end_date <= $local_end_time)) throw new ValidationException("requested booking time slot is not allowed!"); $interval = $end_date->diff($start_date); $minutes = ($interval->d * 24 * 60) + ($interval->h * 60) + $interval->i; if($minutes != $summit->getMeetingRoomBookingSlotLength()) throw new ValidationException("requested booking time slot is not allowed!"); $this->reservations->add($reservation); $reservation->setRoom($this); return $this; } /** * @return float */ public function getTimeSlotCost(): float { return floatval($this->time_slot_cost); } /** * @param float $time_slot_cost */ public function setTimeSlotCost(float $time_slot_cost): void { $this->time_slot_cost = $time_slot_cost; } /** * @return ArrayCollection */ public function getReservations(): ArrayCollection { return $this->reservations; } /** * @param int $id * @return SummitRoomReservation|null */ public function getReservationById(int $id):?SummitRoomReservation{ $criteria = Criteria::create(); $criteria->where(Criteria::expr()->eq('id', intval($id))); $reservation = $this->reservations->matching($criteria)->first(); return $reservation === false ? null : $reservation; } public function clearReservations(){ $this->reservations->clear(); } /** * @return string */ public function getClassName() { return self::ClassName; } /** * @param \DateTime $day should be on local summit day * @return array * @throws ValidationException */ public function getAvailableSlots(\DateTime $day):array{ $availableSlots = []; $summit = $this->summit; $day = $day->setTimezone($summit->getTimeZone())->setTime(0, 0,0); $booking_start_time = $summit->getMeetingRoomBookingStartTime(); if(is_null($booking_start_time)) throw new ValidationException("MeetingRoomBookingStartTime is null!"); $booking_end_time = $summit->getMeetingRoomBookingEndTime(); if(is_null($booking_end_time)) throw new ValidationException("MeetingRoomBookingEndTime is null!"); $booking_slot_len = $summit->getMeetingRoomBookingSlotLength(); $start_datetime = clone $day; $end_datetime = clone $day; $start_datetime->setTime( intval($booking_start_time->format("H")), intval($booking_start_time->format("i")), 0); $start_datetime->setTimezone($summit->getTimeZone()); $end_datetime->setTime( intval($booking_end_time->format("H")), intval($booking_end_time->format("i")), 00); $end_datetime->setTimezone($summit->getTimeZone()); $criteria = Criteria::create(); if(!$summit->isTimeFrameInsideSummitDuration($start_datetime, $end_datetime)) throw new ValidationException("requested day does not belong to summit period"); $criteria ->where(Criteria::expr()->gte('start_datetime', $summit->convertDateFromTimeZone2UTC($start_datetime))) ->andWhere(Criteria::expr()->lte('end_datetime', $summit->convertDateFromTimeZone2UTC($end_datetime))) ->andWhere(Criteria::expr()->notIn("status", [SummitRoomReservation::RequestedRefundStatus, SummitRoomReservation::RefundedStatus])); $reservations = $this->reservations->matching($criteria); while($start_datetime <= $end_datetime) { $current_time_slot_end = clone $start_datetime; $current_time_slot_end->add(new \DateInterval("PT" . $booking_slot_len . 'M')); if($current_time_slot_end<=$end_datetime) $availableSlots[$start_datetime->format('Y-m-d H:i:s').'|'.$current_time_slot_end->format('Y-m-d H:i:s')] = true; $start_datetime = $current_time_slot_end; } foreach ($reservations as $reservation){ if(!$reservation instanceof SummitRoomReservation) continue; $availableSlots[ $summit->convertDateFromUTC2TimeZone($reservation->getStartDatetime())->format("Y-m-d H:i:s") .'|'. $summit->convertDateFromUTC2TimeZone($reservation->getEndDatetime())->format("Y-m-d H:i:s") ] = false; } return $availableSlots; } /** * @param \DateTime $day * @return array * @throws ValidationException */ public function getFreeSlots(\DateTime $day):array{ $slots = $this->getAvailableSlots($day); $free_slots = []; foreach ($slots as $label => $status){ if(!$status) continue; $free_slots[] = $label; } return $free_slots; } /** * @return string */ public function getCurrency(): string { return $this->currency; } /** * @param string $currency */ public function setCurrency(string $currency): void { $this->currency = $currency; } /** * @return mixed */ public function getAttributes() { return $this->attributes; } /** * @param SummitBookableVenueRoomAttributeValue $attribute */ public function addAttribute(SummitBookableVenueRoomAttributeValue $attribute){ if($this->attributes->contains($attribute)) return; $this->attributes->add($attribute); } /** * @param SummitBookableVenueRoomAttributeValue $attribute */ public function removeAttribute(SummitBookableVenueRoomAttributeValue $attribute){ if(!$this->attributes->contains($attribute)) return; $this->attributes->removeElement($attribute); } }