summaryrefslogtreecommitdiff
path: root/app/Model/Timetable.php
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-03-14 20:53:33 -0400
committerFrederic Guillot <fred@kanboard.net>2015-03-14 20:53:33 -0400
commit253996901a10918e3207d46839cdfdc90d200e72 (patch)
tree5e359471d8e7de963277c37c6ff9611181505975 /app/Model/Timetable.php
parent4700139a86d1ef44eabe43edb5a4abff9c645811 (diff)
Calculate the time spent based on the timetable
Diffstat (limited to 'app/Model/Timetable.php')
-rw-r--r--app/Model/Timetable.php88
1 files changed, 88 insertions, 0 deletions
diff --git a/app/Model/Timetable.php b/app/Model/Timetable.php
index eb37cefd..205c2c20 100644
--- a/app/Model/Timetable.php
+++ b/app/Model/Timetable.php
@@ -25,6 +25,94 @@ class Timetable extends Base
private $timeoff;
/**
+ * Calculate effective worked hours by taking into consideration the timetable
+ *
+ * @access public
+ * @param integer $user_id
+ * @param \DateTime $start
+ * @param \DateTime $end
+ * @return float
+ */
+ public function calculateEffectiveDuration($user_id, DateTime $start, DateTime $end)
+ {
+ $end_timetable = clone($end);
+ $end_timetable->setTime(23, 59);
+
+ $timetable = $this->calculate($user_id, $start, $end_timetable);
+ $found_start = false;
+ $hours = 0;
+
+ // The user has no timetable
+ if (empty($this->week)) {
+ return $this->dateParser->getHours($start, $end);
+ }
+
+ foreach ($timetable as $slot) {
+
+ $isStartSlot = $this->dateParser->withinDateRange($start, $slot[0], $slot[1]);
+ $isEndSlot = $this->dateParser->withinDateRange($end, $slot[0], $slot[1]);
+
+ // Start and end are within the same time slot
+ if ($isStartSlot && $isEndSlot) {
+ return $this->dateParser->getHours($start, $end);
+ }
+
+ // We found the start slot
+ if (! $found_start && $isStartSlot) {
+ $found_start = true;
+ $hours = $this->dateParser->getHours($start, $slot[1]);
+ }
+ else if ($found_start) {
+
+ // We found the end slot
+ if ($isEndSlot) {
+ $hours += $this->dateParser->getHours($slot[0], $end);
+ break;
+ }
+ else {
+
+ // Sum hours of the intermediate time slots
+ $hours += $this->dateParser->getHours($slot[0], $slot[1]);
+ }
+ }
+ }
+
+ // The start date was not found in regular hours so we get the nearest time slot
+ if (! empty($timetable) && ! $found_start) {
+ $slot = $this->findClosestTimeSlot($start, $timetable);
+
+ if ($start < $slot[0]) {
+ return $this->calculateEffectiveDuration($user_id, $slot[0], $end);
+ }
+ }
+
+ return $hours;
+ }
+
+ /**
+ * Find the nearest time slot
+ *
+ * @access public
+ * @param DateTime $date
+ * @param array $timetable
+ * @return array
+ */
+ public function findClosestTimeSlot(DateTime $date, array $timetable)
+ {
+ $values = array();
+
+ foreach ($timetable as $slot) {
+ $t1 = abs($slot[0]->getTimestamp() - $date->getTimestamp());
+ $t2 = abs($slot[1]->getTimestamp() - $date->getTimestamp());
+
+ $values[] = min($t1, $t2);
+ }
+
+ asort($values);
+ return $timetable[key($values)];
+ }
+
+ /**
* Get the timetable for a user for a given date range
*
* @access public