public function isValid($data) { $dissolvedData = $data; if ($this->isArray()) { $dissolvedData = $this->_dissolveArrayValue($data, $this->getElementsBelongTo()); } $skipDetailedValidation = true; foreach (array('rule_id', 'start', 'end') as $member) { if (!empty($dissolvedData[$member])) { $skipDetailedValidation = false; $this->rule_id->setRequired(true); $this->start->setRequired(true); $this->end->setRequired(true); } } if (!parent::isValid($data)) { return false; } if ($skipDetailedValidation) { return true; } $data = $dissolvedData; $startDate = new DateTime($data['start']); $endDate = new DateTime($data['end']); if ($startDate > $endDate) { $this->start->addError($this->getTranslator()->translate('The start date must be on or before the end date.')); $this->end->addError($this->getTranslator()->translate('The end date must be on or after the start date.')); return false; } return true; }
public function isValid($data) { if (!parent::isValid($data)) { return false; } $startDate = new DateTime($data['start']); $endDate = new DateTime($data['end']); if ($startDate > $endDate) { $this->start->addError($this->getTranslator()->translate('The start date must be on or before the end date.')); $this->end->addError($this->getTranslator()->translate('The end date must be on or after the start date.')); return false; } $facilityGroup = $this->em->find('Tillikum\\Entity\\FacilityGroup\\FacilityGroup', $data['facilitygroup_id']); $qb = $this->em->createQueryBuilder()->select('c.start, c.end')->from('Tillikum\\Entity\\FacilityGroup\\Config\\Config', 'c')->where('c.start <= :proposedEnd')->andWhere('c.end >= :proposedStart')->andWhere('c.facility_group = :facilityGroup')->setParameter('facilityGroup', $facilityGroup)->setParameter('proposedStart', $startDate)->setParameter('proposedEnd', $endDate); if ($this->entity && isset($this->entity->id)) { $qb->andWhere('c != :entity')->setParameter('entity', $this->entity); } if (count($rows = $qb->getQuery()->getResult()) > 0) { foreach ($rows as $row) { $errorMessage = sprintf($this->getTranslator()->translate('An existing configuration from %s to %s overlaps your intended configuration.'), $row['start']->format('Y-m-d'), $row['end']->format('Y-m-d')); $this->start->addError($errorMessage); $this->end->addError($errorMessage); } return false; } return true; }
public function isValid($data) { if (!parent::isValid($data)) { return false; } $startDate = new DateTime($data['start']); $endDate = new DateTime($data['end']); if ($startDate > $endDate) { $this->start->addError($this->getTranslator()->translate('The start date must be on or before the end date.')); $this->end->addError($this->getTranslator()->translate('The end date must be on or after the start date.')); return false; } $facility = $this->em->find('Tillikum\\Entity\\Facility\\Facility', $data['facility_id']); $holdQueryBuilder = $this->em->createQueryBuilder()->select('h')->from('Tillikum\\Entity\\Facility\\Hold\\Hold', 'h')->where('h.start <= :proposedEnd')->andWhere('h.end >= :proposedStart')->andWhere('h.facility = :facility')->orderBy('h.start')->setParameter('facility', $facility)->setParameter('proposedStart', $startDate)->setParameter('proposedEnd', $endDate); if ($this->entity && isset($this->entity->id)) { $holdQueryBuilder->andWhere('h != :entity')->setParameter('entity', $this->entity); } $holds = $holdQueryBuilder->getQuery()->getResult(); $bookings = $this->em->createQueryBuilder()->select('b')->from('Tillikum\\Entity\\Booking\\Facility\\Facility', 'b')->where('b.start <= :proposedEnd')->andWhere('b.end >= :proposedStart')->andWhere('b.facility = :facility')->orderBy('b.start')->setParameter('facility', $facility)->setParameter('proposedStart', $startDate)->setParameter('proposedEnd', $endDate)->getQuery()->getResult(); $configs = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Config', 'c')->where('c.facility = :facility')->orderBy('c.start')->setParameter('facility', $facility)->getQuery()->getResult(); if (count($holds) > 0) { foreach ($holds as $hold) { $errorMessage = sprintf($this->getTranslator()->translate('An existing hold from %s to %s overlaps your intended hold.'), $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d')); $this->start->addError($errorMessage); $this->end->addError($errorMessage); } return false; } $occupancyInputs = array(new OccupancyInput($startDate, $data['space'] * -1, sprintf('start of the hold you specified from %s to %s', $startDate->format('Y-m-d'), $endDate->format('Y-m-d'))), new OccupancyInput(date_modify(clone $endDate, '+1 day'), $data['space'], sprintf('end of the hold you specified from %s to %s', $startDate->format('Y-m-d'), $endDate->format('Y-m-d')))); foreach ($bookings as $booking) { $occupancyInputs[] = new OccupancyInput($booking->start, -1, sprintf('start of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $booking->end, '+1 day'), 1, sprintf('end of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); } $currentConfigSpace = 0; foreach ($configs as $config) { $occupancyInputs[] = new OccupancyInput($config->start, $config->capacity - $currentConfigSpace, sprintf('start of a facility configuration from %s to %s', $config->start->format('Y-m-d'), $config->end->format('Y-m-d'))); $currentConfigSpace = $config->capacity; } foreach ($holds as $hold) { $occupancyInputs[] = new OccupancyInput($hold->start, $hold->space * -1, sprintf('start of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $hold->end, '+1 day'), $hold->space, sprintf('end of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); } $occupancyEngine = new OccupancyEngine($occupancyInputs); $occupancyResult = $occupancyEngine->run(); if (!$occupancyResult->getIsSuccess()) { $errorMessage = sprintf($this->getTranslator()->translate('There is no available space in this facility to add another ' . 'hold during the specified time period. The problem occurred ' . 'at the %s.'), $occupancyResult->getCulprit()->getDescription()); $this->start->addError($errorMessage); $this->end->addError($errorMessage); return false; } return true; }
public function isValid($data) { $isValid = parent::isValid($data); if (!$isValid) { return $isValid; } foreach ($this->requiredElements as $element) { if (!in_array($element, $data['map'])) { $this->getSubForm('map')->addError("Missing required element ({$element})"); $isValid = false; } } return $isValid; }
public function isValid($data) { if (!parent::isValid($data)) { return false; } $filename = $this->file->getFileName(); if (empty($filename) && empty($data['text'])) { $this->text->addError(sprintf($this->getTranslator()->translate('You must either copy-and-paste from a spreadsheet into' . ' this box or upload a file below.'))); $this->file->addError(sprintf($this->getTranslator()->translate('You must either upload a file here or copy-and-paste from' . ' a spreadsheet into the box above.'))); return false; } if (!empty($filename) && !empty($data['text'])) { $this->text->addError(sprintf($this->getTranslator()->translate('You must either copy-and-paste from a spreadsheet into' . ' this box or upload a file below, but not both.'))); $this->file->addError(sprintf($this->getTranslator()->translate('You must either upload a file here or copy-and-paste from' . ' a spreadsheet into the box above, but not both.'))); return false; } if (!empty($data['text'])) { // As far as I can tell there can't really be any errors here. $this->rawArray = array(); foreach (explode("\r\n", trim($data['text'])) as $row) { $this->rawArray[] = str_getcsv($row, "\t"); } } elseif (!empty($filename)) { if (!$this->file->receive()) { $this->file->addError(sprintf($this->getTranslator()->translate('There was a problem receiving the file you uploaded. If' . ' you try again and the error persists, please contact' . ' your support staff.'))); return false; } $fp = fopen($filename, 'rb'); if ($fp === false) { $this->file->addError(sprintf($this->getTranslator()->translate('There was a problem reading the file you uploaded. If' . ' you try again and the error persists, please contact' . ' your support staff.'))); return false; } $this->rawArray = array(); while ($row = fgetcsv($fp)) { $this->rawArray[] = $row; } } return true; }
public function checkMappedData($map, $rows) { $personGateway = new \TillikumX\Model\PersonGateway(); $identity = \Zend_Auth::getInstance()->hasIdentity() ? Zend_Auth::getInstance()->getIdentity() : '_system'; $rowNum = 1; $this->data = $rangesByFacility = array(); foreach ($rows as $row) { $person = $personGateway->fetch($row[$map['id']]); if (null === $person) { return array('result' => false, 'reason' => sprintf('The person with ID %s does not exist.', $row[$map['id']]), 'row' => $rowNum); } $bookingInput = array('facility' => $row[$map['booking_facility']], 'start' => $row[$map['booking_start']], 'end' => $row[$map['booking_end']]); $rates = array(); for ($i = 0; $i < 3; $i++) { $mapOffset = $i + 1; if (!isset($map["booking_rate{$mapOffset}_id"]) || !isset($row[$map["booking_rate{$mapOffset}_id"]])) { continue; } $rate = array('rate' => $row[$map["booking_rate{$mapOffset}_id"]]); if (isset($map["booking_rate{$mapOffset}_start"])) { $rate['start'] = $row[$map["booking_rate{$mapOffset}_start"]]; } if (isset($map["booking_rate{$mapOffset}_end"])) { $rate['end'] = $row[$map["booking_rate{$mapOffset}_end"]]; } $bookingInput['rates'][] = $rate; } if (isset($map['booking_billing_effective'])) { $bookingInput['billing_effective'] = $row[$map['booking_billing_effective']]; } if (isset($map['booking_billing_through'])) { $bookingInput['billing_through'] = $row[$map['booking_billing_through']]; } $mealplanInput = array(); if (isset($map['mealplan_plan'])) { $mealplanInput['plan'] = $row[$map['mealplan_plan']]; } if (isset($map['mealplan_start'])) { $mealplanInput['start'] = $row[$map['mealplan_start']]; } if (isset($map['mealplan_end'])) { $mealplanInput['end'] = $row[$map['mealplan_end']]; } for ($i = 0; $i < 1; $i++) { $mapOffset = $i + 1; if (!isset($map["mealplan_rate{$mapOffset}_id"]) || !isset($row[$map["mealplan_rate{$mapOffset}_id"]])) { continue; } $rate = array('rate' => $row[$map["mealplan_rate{$mapOffset}_id"]]); if (isset($map["mealplan_rate{$mapOffset}_start"])) { $rate['start'] = $row[$map["mealplan_rate{$mapOffset}_start"]]; } if (isset($map["mealplan_rate{$mapOffset}_end"])) { $rate['end'] = $row[$map["mealplan_rate{$mapOffset}_end"]]; } $mealplanInput['rates'][] = $rate; } if (isset($map['mealplan_billing_effective'])) { $mealplanInput['billing_effective'] = $row[$map['mealplan_billing_effective']]; } if (isset($map['mealplan_billing_through'])) { $mealplanInput['billing_through'] = $row[$map['mealplan_billing_through']]; } // Set up our form $bookingForm = new \Tillikum_Form(); $bookingForm->setElementsBelongTo('booking'); $facilitySubForm = new \Tillikum\Form\Booking\Facility(); $facilitySubForm->setElementsBelongTo('facility'); $facilitySubForm->setPerson($person); $bookingForm->addSubForm($facilitySubForm, 'facility'); $mealplanSubForm = new \Tillikum\Form\Booking\Mealplan(); $mealplanSubForm->setElementsBelongTo('mealplan'); $mealplanSubForm->setPerson($person); $mealplanSubForm->plan->setRequired(false); $mealplanSubForm->start->setRequired(false); $mealplanSubForm->end->setRequired(false); $bookingForm->addSubForm($mealplanSubForm, 'mealplan'); if (array_key_exists($bookingInput['facility'], $rangesByFacility)) { foreach ($rangesByFacility[$bookingInput['facility']] as $range) { $facilitySubForm->addExtraDateRange($range); } } $massInput = array('facility' => $bookingInput, 'mealplan' => $mealplanInput); if (!$bookingForm->isValid($massInput)) { $it = new RecursiveArrayIterator($bookingForm->getMessages()); $itit = new RecursiveIteratorIterator($it); foreach ($itit as $message) { return array('result' => false, 'reason' => $message, 'row' => $rowNum); } } $values = $bookingForm->getValues(true); $facilityBooking = $values['facility']['booking']; $facilityBooking->created_by = $identity; $facilityBooking->updated_by = $identity; $ffnHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('FullFacilityName'); $view = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer')->view; $facilityNameArray = $ffnHelper->fullFacilityName($facilityBooking->facility, null, $facilityBooking->start); if ($facilityBooking->billing) { $bookingCharges = $facilityBooking->processCharges($view->fullFacilityName($facilityNameArray)); foreach ($bookingCharges as $charge) { $charge->created_by = $identity; $this->data[$person->id]['charges'][] = $charge; } } $this->data[$person->id]['bookings'][] = $facilityBooking; $mealplanBooking = $values['mealplan']['booking']; if (null !== $mealplanBooking) { $mealplanBooking->created_by = $identity; $mealplanBooking->updated_by = $identity; if ($mealplanBooking->billing) { $mealplanCharges = $mealplanBooking->processCharges($mealplanBooking->plan); foreach ($mealplanCharges as $charge) { $charge->created_by = $identity; $this->data[$person->id]['charges'][] = $charge; } } $this->data[$person->id]['mealplans'][] = $mealplanBooking; } $rangesByFacility[$bookingInput['facility']][] = new \Vo\DateRange($facilityBooking->start, $facilityBooking->end); } return array('result' => true); }
public function isValid($data) { if (!parent::isValid($data)) { return false; } if ($this->isArray()) { $data = $this->_dissolveArrayValue($data, $this->getElementsBelongTo()); } $startDate = new DateTime($data['start']); $endDate = new DateTime($data['end']); if ($startDate > $endDate) { $this->start->addError($this->getTranslator()->translate('The start date must be on or before the end date.')); $this->end->addError($this->getTranslator()->translate('The end date must be on or after the start date.')); return false; } $bookingRange = new DateRange($startDate, $endDate); $bookingFacility = $this->em->find('Tillikum\\Entity\\Facility\\Facility', $data['facility_id']); $person = $this->booking->person; $bookings = $this->em->createQueryBuilder()->select('b')->from('Tillikum\\Entity\\Booking\\Facility\\Facility', 'b')->where('b.start <= :proposedEnd')->andWhere('b.end >= :proposedStart')->andWhere('b.facility = :facility')->andWhere('b.person != :person')->orderBy('b.start')->setParameter('facility', $bookingFacility)->setParameter('person', $person)->setParameter('proposedStart', $bookingRange->getStart())->setParameter('proposedEnd', $bookingRange->getEnd())->getQuery()->getResult(); $configs = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Config', 'c')->where('c.facility = :facility')->orderBy('c.start')->setParameter('facility', $bookingFacility)->getQuery()->getResult(); $holds = $this->em->createQueryBuilder()->select('h')->from('Tillikum\\Entity\\Facility\\Hold\\Hold', 'h')->where('h.start <= :proposedEnd')->andWhere('h.end >= :proposedStart')->andWhere('h.facility = :facility')->orderBy('h.start')->setParameter('facility', $bookingFacility)->setParameter('proposedStart', $bookingRange->getStart())->setParameter('proposedEnd', $bookingRange->getEnd())->getQuery()->getResult(); $occupancyInputs = array(new OccupancyInput($bookingRange->getStart(), -1, sprintf('start of the booking range you specified from %s to %s', $bookingRange->getStart()->format('Y-m-d'), $bookingRange->getEnd()->format('Y-m-d'))), new OccupancyInput(date_modify(clone $bookingRange->getEnd(), '+1 day'), 1, sprintf('end of the booking range you specified from %s to %s', $bookingRange->getStart()->format('Y-m-d'), $bookingRange->getEnd()->format('Y-m-d')))); foreach ($bookings as $booking) { $occupancyInputs[] = new OccupancyInput($booking->start, -1, sprintf('start of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $booking->end, '+1 day'), 1, sprintf('end of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); if (!empty($booking->person->gender)) { $bookingGenderSpec = isset($bookingGenderSpec) ? $bookingGenderSpec->andSpec(new GenderMatchSpecification($booking->person->gender)) : new GenderMatchSpecification($booking->person->gender); } } $currentConfigSpace = 0; foreach ($configs as $config) { $occupancyInputs[] = new OccupancyInput($config->start, $config->capacity - $currentConfigSpace, sprintf('start of a facility configuration from %s to %s', $config->start->format('Y-m-d'), $config->end->format('Y-m-d'))); $currentConfigSpace = $config->capacity; if (!empty($config->gender)) { $facilityGenderSpec = isset($facilityGenderSpec) ? $facilityGenderSpec->andSpec(new GenderMatchSpecification($config->gender)) : new GenderMatchSpecification($config->gender); } if (!empty($config->suite)) { $suiteConfigs = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Room\\Room', 'c')->where('c.start <= :proposedEnd')->andWhere('c.end >= :proposedStart')->andWhere('c.suite = :suite')->setParameter('proposedStart', $bookingRange->getStart())->setParameter('proposedEnd', $bookingRange->getEnd())->setParameter('suite', $config->suite)->getQuery()->getResult(); foreach ($suiteConfigs as $suiteConfig) { if (!empty($suiteConfig->gender)) { $suiteGenderSpec = isset($suiteGenderSpec) ? $suiteGenderSpec->andSpec(new GenderMatchSpecification($suiteConfig->gender)) : new GenderMatchSpecification($suiteConfig->gender); } } } } foreach ($holds as $hold) { $occupancyInputs[] = new OccupancyInput($hold->start, $hold->space * -1, sprintf('start of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $hold->end, '+1 day'), $hold->space, sprintf('end of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); if (!empty($hold->gender)) { $holdGenderSpec = isset($holdGenderSpec) ? $holdGenderSpec->andSpec(new GenderMatchSpecification($hold->gender)) : new GenderMatchSpecification($hold->gender); } } $occupancyEngine = new OccupancyEngine($occupancyInputs); $occupancyResult = $occupancyEngine->run(); if (!$occupancyResult->getIsSuccess()) { $this->facility_name->addError(sprintf($this->getTranslator()->translate('There is no available space in this facility to book another' . ' resident during the specified time period. The problem' . ' occurred at the %s.'), $occupancyResult->getCulprit()->getDescription())); return false; } if (isset($bookingGenderSpec) && !$bookingGenderSpec->isSatisfiedBy($person->gender)) { $this->addWarning(sprintf($this->getTranslator()->translate('The person you are booking with gender %s did not meet' . ' the gender requirements of the other people booked' . ' to this facility for the desired time period.'), $person->gender)); } if (isset($facilityGenderSpec) && !$facilityGenderSpec->isSatisfiedBy($person->gender)) { $this->addWarning(sprintf($this->getTranslator()->translate('The person you are booking with gender %s did not meet' . ' the gender requirements of the configurations for this' . ' facility for the desired time period.'), $person->gender)); } if (isset($holdGenderSpec) && !$holdGenderSpec->isSatisfiedBy($person->gender)) { $this->addWarning(sprintf($this->getTranslator()->translate('The person you are booking with gender %s did not meet' . ' the gender requirements of the holds on this facility' . ' for the desired time period.'), $person->gender)); } if (isset($suiteGenderSpec) && !$suiteGenderSpec->isSatisfiedBy($person->gender)) { $this->addWarning(sprintf($this->getTranslator()->translate('The person you are booking with gender %s did not meet' . ' the gender requirements of the other people booked to' . ' this suite for the specified time period.'), $person->gender)); } return true; }
public function isValid($data) { if (!parent::isValid($data)) { return false; } $startDate = new DateTime($data['start']); $endDate = new DateTime($data['end']); if ($startDate > $endDate) { $this->start->addError($this->getTranslator()->translate('The start date must be on or before the end date.')); $this->end->addError($this->getTranslator()->translate('The end date must be on or after the start date.')); return false; } $configRange = new DateRange($startDate, $endDate); $facility = $this->em->find('Tillikum\\Entity\\Facility\\Facility', $data['facility_id']); $bookings = $this->em->createQueryBuilder()->select('b')->from('Tillikum\\Entity\\Booking\\Facility\\Facility', 'b')->where('b.start <= :proposedEnd')->andWhere('b.end >= :proposedStart')->andWhere('b.facility = :facility')->orderBy('b.start')->setParameter('facility', $facility)->setParameter('proposedStart', $configRange->getStart())->setParameter('proposedEnd', $configRange->getEnd())->getQuery()->getResult(); $qb = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Config', 'c')->where('c.facility = :facility')->orderBy('c.start')->setParameter('facility', $this->entity->facility); if ($this->entity && isset($this->entity->id)) { $qb->andWhere('c != :entity')->setParameter('entity', $this->entity); } $configs = $qb->getQuery()->getResult(); $overlappingQueryBuilder = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Config', 'c')->where('c.start <= :proposedStart')->andWhere('c.end >= :proposedEnd')->andWhere('c.facility = :facility')->setParameter('proposedStart', $configRange->getStart())->setParameter('proposedEnd', $configRange->getEnd())->setParameter('facility', $this->entity->facility); if ($this->entity && isset($this->entity->id)) { $overlappingQueryBuilder->andWhere('c != :entity')->setParameter('entity', $this->entity); } $overlappingConfigs = $overlappingQueryBuilder->getQuery()->getResult(); $holds = $this->em->createQueryBuilder()->select('h')->from('Tillikum\\Entity\\Facility\\Hold\\Hold', 'h')->where('h.start <= :proposedEnd')->andWhere('h.end >= :proposedStart')->andWhere('h.facility = :facility')->orderBy('h.start')->setParameter('facility', $facility)->setParameter('proposedStart', $configRange->getStart())->setParameter('proposedEnd', $configRange->getEnd())->getQuery()->getResult(); if (count($overlappingConfigs) > 0) { foreach ($overlappingConfigs as $config) { $errorMessage = sprintf($this->getTranslator()->translate('An existing configuration from %s to %s overlaps your intended configuration.'), $config->start->format('Y-m-d'), $config->end->format('Y-m-d')); $this->start->addError($errorMessage); $this->end->addError($errorMessage); } return false; } $occupancyInputs = array(new OccupancyInput($configRange->getStart(), $data['capacity'], sprintf('start of the facility configuration you specified from %s to %s', $configRange->getStart()->format('Y-m-d'), $configRange->getEnd()->format('Y-m-d')))); foreach ($configs as $config) { $occupancyInputs[] = new OccupancyInput($config->start, $config->capacity, sprintf('start of a facility configuration from %s to %s', $config->start->format('Y-m-d'), $config->end->format('Y-m-d'))); if (!empty($data['suite'])) { $suiteConfigs = $this->em->createQueryBuilder()->select('c')->from('Tillikum\\Entity\\Facility\\Config\\Room\\Room', 'c')->join('c.suite', 's')->where('c.start <= :proposedEnd')->andWhere('c.end >= :proposedStart')->andWhere('s.id = :suiteId')->setParameter('proposedStart', $configRange->getStart())->setParameter('proposedEnd', $configRange->getEnd())->setParameter('suiteId', $data['suite'])->getQuery()->getResult(); foreach ($suiteConfigs as $suiteConfig) { if (!empty($suiteConfig->gender)) { $suiteGenderSpec = isset($suiteGenderSpec) ? $suiteGenderSpec->andSpec(new GenderMatchSpecification($suiteConfig->gender)) : new GenderMatchSpecification($suiteConfig->gender); } } } } // We need to re-sort since the user-specified input will not be sorted usort($occupancyInputs, function ($a, $b) { if ($a->getDate() == $b->getDate()) { return 0; } return $a->getDate() < $b->getDate() ? -1 : 1; }); // Actually calculate moments after re-sorting $currentConfigSpace = 0; foreach ($occupancyInputs as $idx => $input) { $oldValue = $input->getValue(); $occupancyInputs[$idx] = new OccupancyInput($input->getDate(), $input->getValue() - $currentConfigSpace, $input->getDescription()); $currentConfigSpace = $oldValue; } foreach ($bookings as $booking) { $occupancyInputs[] = new OccupancyInput($booking->start, -1, sprintf('start of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $booking->end, '+1 day'), 1, sprintf('end of a booking from %s to %s', $booking->start->format('Y-m-d'), $booking->end->format('Y-m-d'))); if (!empty($booking->person->gender)) { $bookingGenderSpec = isset($bookingGenderSpec) ? $bookingGenderSpec->andSpec(new GenderMatchSpecification($booking->person->gender)) : new GenderMatchSpecification($booking->person->gender); } } foreach ($holds as $hold) { $occupancyInputs[] = new OccupancyInput($hold->start, $hold->space * -1, sprintf('start of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); $occupancyInputs[] = new OccupancyInput(date_modify(clone $hold->end, '+1 day'), $hold->space, sprintf('end of a hold from %s to %s', $hold->start->format('Y-m-d'), $hold->end->format('Y-m-d'))); if (!empty($hold->gender)) { $holdGenderSpec = isset($holdGenderSpec) ? $holdGenderSpec->andSpec(new GenderMatchSpecification($hold->gender)) : new GenderMatchSpecification($hold->gender); } } $occupancyEngine = new OccupancyEngine($occupancyInputs); $occupancyResult = $occupancyEngine->run(); if (!$occupancyResult->getIsSuccess()) { $this->capacity->addError(sprintf($this->getTranslator()->translate('There are too many claims on space in this facility ' . 'to change the capacity of this configuration. The ' . 'problem occurred at the %s.'), $occupancyResult->getCulprit()->getDescription())); return false; } if (isset($holdGenderSpec) && !$holdGenderSpec->isSatisfiedBy($data['gender'])) { $this->addWarning(sprintf($this->getTranslator()->translate('The desired configuration gender does not meet the' . ' gender requirements of an overlapping facility hold.'))); } if (isset($bookingGenderSpec) && !$bookingGenderSpec->isSatisfiedBy($data['gender'])) { $this->addWarning(sprintf($this->getTranslator()->translate('The desired configuration gender does not meet the' . ' gender requirements of an overlapping booking.'))); } if (isset($suiteGenderSpec) && !$suiteGenderSpec->isSatisfiedBy($data['gender'])) { $this->addWarning(sprintf($this->getTranslator()->translate('The desired configuration gender does not meet the' . ' gender requirements of an overlapping booking in a' . ' related suite.'))); } return true; }