Skip to content

Commit

Permalink
Schedule Entry - getOccurrences algo.
Browse files Browse the repository at this point in the history
Use end date, based on grace period, when getting occurrences as opposed to
count. This helps avoid accidental fast-forwarding of date counter since
only entries in scope are considered.

The commit also addresses infinite loop when counting time.
  • Loading branch information
protich committed Dec 19, 2019
1 parent 3da5bd7 commit 0184473
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
18 changes: 12 additions & 6 deletions include/class.businesshours.php
Expand Up @@ -52,25 +52,30 @@ public function getSchedule() {
}

// Intitialize occurrenses buckets
private function initOccurrences(Datetime $date) {
private function initOccurrences(Datetime $date, $grace_period_hrs=72) {

$dt = clone $date;
// Start from next day if current date is already processed
if ($this->workhours[$dt->format('Y-m-d')])
if (isset($this->workhours[$dt->format('Y-m-d')]))
$dt->modify('+1 day');

// Apply grace period
$period = clone $dt;
$period->modify("+$grace_period_hrs hour");

// Reset occurrense buckets
$this->workhours = $this->holidays = array();
// Init workhours
foreach ($this->getSchedule()->getEntries() as $entry)
$this->workhours += $entry->getOccurrences($dt, null, 4);
$this->workhours += $entry->getOccurrences($dt,
$period->format('Y-m-d'));
ksort($this->workhours);
// Init holidays taking into account end date of the workhours in
// the current scope.
$enddate = array_pop(array_keys($this->workhours));
foreach ($this->getSchedule()->getHolidaysSchedules() as $schedule) {
foreach ($schedule->getEntries() as $entry)
$this->holidays += $entry->getOccurrences($dt, $enddate, 5);
$this->holidays += $entry->getOccurrences($dt, $enddate);
}
ksort($this->holidays);

Expand Down Expand Up @@ -131,10 +136,11 @@ public function addWorkingHours(Datetime $date, $hours, &$auditlog=array()) {
$holiday->getHours(),
$holiday->getSchedule()->getName(),
$holiday->getDesc()));

//Move the date to end of the day of the holiday
$date->modify("$d ".$holiday->getEndsTime());
// If the holiday is a full day then assume the day is a goner
if ($holiday->isFullDay()) continue;
//Move the date to end of the partial day of the holiday
$date->modify("$d ".$holiday->getEndsTime());
$partial = true;
// See if we need to recover any time prior to start of
// holiday e.g if the day starts at 8am but the holiday
Expand Down
14 changes: 8 additions & 6 deletions include/class.schedule.php
Expand Up @@ -846,16 +846,18 @@ function next() {
return $current;
}

function getOccurrences($start=null, $end=null, $num=2) {
function getOccurrences($start=null, $end=null, $num=5) {
$occurrences = array();
if (($current = $this->getCurrent($start))) {
$occurrences[$current->format('Y-m-d')] = $this;
$start = $start ?: $current;
while (count($occurrences) < $num) {
if (!($next=$this->next()))
break;
$date = $current->format('Y-m-d');
$occurrences[$date] = $this;
if ($end && strtotime($date) >= strtotime($end))
if ($end && strtotime($date) > strtotime($end))
break;
if (strtotime($date) >= strtotime($start->format('Y-m-d')))
$occurrences[$date] = $this;

if (!($current=$this->next()))
break;
}
}
Expand Down

0 comments on commit 0184473

Please sign in to comment.