Created
March 31, 2023 13:28
-
-
Save ggagosh/c27b3fa805c2a2519225031d9505565e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Validates the entity against its configuration. | |
* | |
* @return bool | |
* TRUE if the entity is valid, FALSE otherwise. | |
*/ | |
public function validate(): bool { | |
foreach ($this->config as $type => $type_config) { | |
// Check if the entity has any days of this type. | |
if (!isset($this->data[$type])) { | |
continue; | |
} | |
// Check if the entity has too many days of this type. | |
$count = count($this->data[$type]); | |
if ($count > $type_config['have']) { | |
return FALSE; | |
} | |
// Check if the entity has too many days of this type in a row. | |
$max = $type_config['max']; | |
$current = 0; | |
foreach ($this->data[$type] as $day) { | |
if (isset($prev) && ($day->getTimestamp() - $prev->getTimestamp()) / (60 * 60 * 24) <= 1) { | |
$current++; | |
if ($current > $max) { | |
return FALSE; | |
} | |
} | |
else { | |
$current = 1; | |
} | |
$prev = $day; | |
} | |
// Check if the entity has enough days between days of this type. | |
$between = $type_config['between']; | |
foreach ($this->data[$type] as $key => $day) { | |
if (isset($prev) && ($day->getTimestamp() - $prev->getTimestamp()) / (60 * 60 * 24) < $between) { | |
return FALSE; | |
} | |
$prev = $day; | |
} | |
// Check if the entity has enough days before the first day of this type. | |
$pre = $type_config['pre']; | |
$first_day = min($this->data[$type]); | |
$days_since_first_day = ($first_day->getTimestamp() - $this->start_date->getTimestamp()) / (60 * 60 * 24); | |
if ($days_since_first_day < $pre) { | |
return FALSE; | |
} | |
// Check if the entity has days of this type that are forced to be in a row. | |
if ($type_config['force_together']) { | |
foreach ($this->data[$type] as $key => $day) { | |
if (isset($prev) && ($day->getTimestamp() - $prev->getTimestamp()) / (60 * 60 * 24) > 1) { | |
return FALSE; | |
} | |
$prev = $day; | |
} | |
} | |
} | |
return TRUE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Calculate number of days between two dates, excluding weekends. | |
* | |
* @param \DateTime $start_date | |
* The start date. | |
* @param \DateTime $end_date | |
* The end date. | |
* | |
* @return int | |
* The number of days. | |
*/ | |
protected function calculateDays(\DateTime $start_date, \DateTime $end_date) { | |
$days = 0; | |
$interval = new \DateInterval('P1D'); | |
$period = new \DatePeriod($start_date, $interval, $end_date->modify('+1 day')); | |
foreach ($period as $date) { | |
if ($date->format('N') < 6) { | |
$days++; | |
} | |
} | |
return $days; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Drupal\Core\Entity\EntityChangedTrait; | |
use Drupal\Core\Entity\ContentEntityBase; | |
class MyEntity extends ContentEntityBase implements MyEntityInterface { | |
use EntityChangedTrait; | |
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { | |
$fields = parent::baseFieldDefinitions($entity_type); | |
$fields['start_date'] = BaseFieldDefinition::create('datetime') | |
->setLabel(t('Start Date')) | |
->setRequired(TRUE); | |
$fields['end_date'] = BaseFieldDefinition::create('datetime') | |
->setLabel(t('End Date')) | |
->setRequired(TRUE); | |
return $fields; | |
} | |
public function getStartDate() { | |
return $this->get('start_date')->date; | |
} | |
public function setStartDate(\DateTime $start_date) { | |
$this->set('start_date', $start_date); | |
return $this; | |
} | |
public function getEndDate() { | |
return $this->get('end_date')->date; | |
} | |
public function setEndDate(\DateTime $end_date) { | |
$this->set('end_date', $end_date); | |
return $this; | |
} | |
public function validate(MyEntityInterface $entity) { | |
$errors = []; | |
// Check if start date is before end date. | |
if ($entity->getStartDate() >= $entity->getEndDate()) { | |
$errors[] = t('Start date must be before end date.'); | |
} | |
// Check if entity is within allowed maximum number of days. | |
$entity_type = $entity->getEntityType()->id(); | |
$days = $this->calculateDays($entity->getStartDate(), $entity->getEndDate()); | |
if ($entity_type == 'vacation' && $days > 10) { | |
$errors[] = t('Vacation cannot exceed 10 days.'); | |
} | |
elseif ($entity_type == 'day_off' && $days > 1) { | |
$errors[] = t('Day off cannot exceed 1 day.'); | |
} | |
elseif ($entity_type == 'sick_leave' && $days > 1) { | |
$errors[] = t('Sick leave cannot exceed 1 day.'); | |
} | |
elseif ($entity_type == 'medical_leave' && $days > 60) { | |
$errors[] = t('Medical leave cannot exceed 60 days.'); | |
} | |
elseif ($entity_type == 'unpaid_leave' && $days > 10) { | |
$errors[] = t('Unpaid leave cannot exceed 10 days.'); | |
} | |
// Check if entity is within allowed minimum number of days. | |
$pre_days = $this->calculateDays($this->getPreviousEndDate(), $entity->getStartDate()); | |
if ($entity_type == 'vacation' && $pre_days < 10) { | |
$errors[] = t('There must be at least 10 working days between vacation periods.'); | |
} | |
elseif ($entity_type == 'day_off' && $pre_days < 1) { | |
$errors[] = t('There must be at least 1 day between day off periods.'); | |
} | |
// Check if entity is allowed to be forced together. | |
if ($entity_type == 'vacation' && !$entity->isForceTogether()) { | |
$errors[] = t('Vacation days must be taken in a row.'); | |
} | |
elseif ($entity_type == 'unpaid_leave' && !$entity->isForceTogether()) { | |
$errors[] = t('Unpaid leave days must be taken in a row.'); | |
} | |
return $errors; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Drupal\Core\Entity\ContentEntityInterface; | |
interface MyEntityInterface extends ContentEntityInterface { | |
/** | |
* Gets the start date of the entity. | |
* | |
* @return \DateTime | |
* The start date of the entity. | |
*/ | |
public function getStartDate(); | |
/** | |
* Sets the start date of the entity. | |
* | |
* @param \DateTime $start_date | |
* The start date of the entity. | |
* | |
* @return $this | |
*/ | |
public function setStartDate(\DateTime $start_date); | |
/** | |
* Gets the end date of the entity. | |
* | |
* @return \DateTime | |
* The end date of the entity. | |
*/ | |
public function getEndDate(); | |
/** | |
* Sets the end date of the entity. | |
* | |
* @param \DateTime $end_date | |
* The end date of the entity. | |
* | |
* @return $this | |
*/ | |
public function setEndDate(\DateTime $end_date); | |
/** | |
* Validates the entity. | |
* | |
* @param \Drupal\my_module\Entity\MyEntityInterface $entity | |
* The entity to validate. | |
* | |
* @return array | |
* An array of error messages. | |
*/ | |
public function validate(MyEntityInterface $entity); | |
/** | |
* Checks if the entity is valid. | |
* | |
* @return bool | |
* TRUE if the entity is valid, FALSE otherwise. | |
*/ | |
public function isValid(); | |
/** | |
* Checks if the entity is a vacation day. | |
* | |
* @return bool | |
* TRUE if the entity is a vacation day, FALSE otherwise. | |
*/ | |
public function isVacation(); | |
/** | |
* Checks if the entity is a day off. | |
* | |
* @return bool | |
* TRUE if the entity is a day off, FALSE otherwise. | |
*/ | |
public function isDayOff(); | |
/** | |
* Checks if the entity is a sick leave day. | |
* | |
* @return bool | |
* TRUE if the entity is a sick leave day, FALSE otherwise. | |
*/ | |
public function isSickLeave(); | |
/** | |
* Checks if the entity is a medical leave day. | |
* | |
* @return bool | |
* TRUE if the entity is a medical leave day, FALSE otherwise. | |
*/ | |
public function isMedicalLeave(); | |
/** | |
* Checks if the entity is an unpaid leave day. | |
* | |
* @return bool | |
* TRUE if the entity is an unpaid leave day, FALSE otherwise. | |
*/ | |
public function isUnpaidLeave(); | |
/** | |
* Checks if the entity is a working day. | |
* | |
* @return bool | |
* TRUE if the entity is a working day, FALSE otherwise. | |
*/ | |
public function isWorkingDay(); | |
} |
Author
ggagosh
commented
Mar 31, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment