Add user timetables

This commit is contained in:
Frederic Guillot
2015-03-09 21:37:10 -04:00
parent 7328995645
commit c870508923
45 changed files with 2014 additions and 5 deletions

194
app/Model/Timetable.php Normal file
View File

@@ -0,0 +1,194 @@
<?php
namespace Model;
use DateTime;
use DateInterval;
/**
* Timetable
*
* @package model
* @author Frederic Guillot
*/
class Timetable extends Base
{
/**
* User time slots
*
* @access private
* @var array
*/
private $day;
private $week;
private $overtime;
private $timeoff;
/**
* Get the timetable for a user for a given date range
*
* @access public
* @param integer $user_id
* @param \DateTime $start
* @param \DateTime $end
* @return array
*/
public function calculate($user_id, DateTime $start, DateTime $end)
{
$timetable = array();
$this->day = $this->timetableDay->getByUser($user_id);
$this->week = $this->timetableWeek->getByUser($user_id);
$this->overtime = $this->timetableExtra->getByUserAndDate($user_id, $start->format('Y-m-d'), $end->format('Y-m-d'));
$this->timeoff = $this->timetableOff->getByUserAndDate($user_id, $start->format('Y-m-d'), $end->format('Y-m-d'));
for ($today = clone($start); $today <= $end; $today->add(new DateInterval('P1D'))) {
$week_day = $today->format('N');
$timetable = array_merge($timetable, $this->getWeekSlots($today, $week_day));
$timetable = array_merge($timetable, $this->getOvertimeSlots($today, $week_day));
}
return $timetable;
}
/**
* Return worked time slots for the given day
*
* @access public
* @param \DateTime $today
* @param string $week_day
* @return array
*/
public function getWeekSlots(DateTime $today, $week_day)
{
$slots = array();
$dayoff = $this->getDayOff($today);
if (! empty($dayoff) && $dayoff['all_day'] == 1) {
return array();
}
foreach ($this->week as $slot) {
if ($week_day == $slot['day']) {
$slots = array_merge($slots, $this->getDayWorkSlots($slot, $dayoff, $today));
}
}
return $slots;
}
/**
* Get the overtime time slots for the given day
*
* @access public
* @param \DateTime $today
* @param string $week_day
* @return array
*/
public function getOvertimeSlots(DateTime $today, $week_day)
{
$slots = array();
foreach ($this->overtime as $slot) {
$day = new DateTime($slot['date']);
if ($week_day == $day->format('N')) {
if ($slot['all_day'] == 1) {
$slots = array_merge($slots, $this->getDaySlots($today));
}
else {
$slots[] = $this->getTimeSlot($slot, $day);
}
}
}
return $slots;
}
/**
* Get worked time slots and remove time off
*
* @access public
* @param array $slot
* @param array $dayoff
* @param \DateTime $today
* @return array
*/
public function getDayWorkSlots(array $slot, array $dayoff, DateTime $today)
{
$slots = array();
if (! empty($dayoff) && $dayoff['start'] < $slot['end']) {
if ($dayoff['start'] > $slot['start']) {
$slots[] = $this->getTimeSlot(array('end' => $dayoff['start']) + $slot, $today);
}
if ($dayoff['end'] < $slot['end']) {
$slots[] = $this->getTimeSlot(array('start' => $dayoff['end']) + $slot, $today);
}
}
else {
$slots[] = $this->getTimeSlot($slot, $today);
}
return $slots;
}
/**
* Get regular day work time slots
*
* @access public
* @param \DateTime $today
* @return array
*/
public function getDaySlots(DateTime $today)
{
$slots = array();
foreach ($this->day as $day) {
$slots[] = $this->getTimeSlot($day, $today);
}
return $slots;
}
/**
* Get the start and end time slot for a given day
*
* @access public
* @param array $slot
* @param \DateTime $today
* @return array
*/
public function getTimeSlot(array $slot, DateTime $today)
{
$date = $today->format('Y-m-d');
return array(
new DateTime($date.' '.$slot['start']),
new DateTime($date.' '.$slot['end']),
);
}
/**
* Return day off time slot
*
* @access public
* @param \DateTime $today
* @return array
*/
public function getDayOff(DateTime $today)
{
foreach ($this->timeoff as $day) {
if ($day['date'] === $today->format('Y-m-d')) {
return $day;
}
}
return array();
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Model;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Timetable Workweek
*
* @package model
* @author Frederic Guillot
*/
class TimetableDay extends Base
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'timetable_day';
/**
* Get the timetable for a given user
*
* @access public
* @param integer $user_id User id
* @return array
*/
public function getByUser($user_id)
{
return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('start')->findAll();
}
/**
* Add a new time slot in the database
*
* @access public
* @param integer $user_id User id
* @param string $start Start hour (24h format)
* @param string $end End hour (24h format)
* @return boolean|integer
*/
public function create($user_id, $start, $end)
{
$values = array(
'user_id' => $user_id,
'start' => $start,
'end' => $end,
);
return $this->persist(self::TABLE, $values);
}
/**
* Remove a specific time slot
*
* @access public
* @param integer $slot_id
* @return boolean
*/
public function remove($slot_id)
{
return $this->db->table(self::TABLE)->eq('id', $slot_id)->remove();
}
/**
* Validate creation
*
* @access public
* @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateCreation(array $values)
{
$v = new Validator($values, array(
new Validators\Required('user_id', t('Field required')),
new Validators\Required('start', t('Field required')),
new Validators\Required('end', t('Field required')),
));
return array(
$v->execute(),
$v->getErrors()
);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Model;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Timetable over-time
*
* @package model
* @author Frederic Guillot
*/
class TimetableExtra extends TimetableOff
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'timetable_extra';
}

125
app/Model/TimetableOff.php Normal file
View File

@@ -0,0 +1,125 @@
<?php
namespace Model;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Timetable time off
*
* @package model
* @author Frederic Guillot
*/
class TimetableOff extends Base
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'timetable_off';
/**
* Get query to fetch everything (pagination)
*
* @access public
* @param integer $user_id User id
* @return \PicoDb\Table
*/
public function getUserQuery($user_id)
{
return $this->db->table(static::TABLE)->eq('user_id', $user_id);
}
/**
* Get the timetable for a given user
*
* @access public
* @param integer $user_id User id
* @return array
*/
public function getByUser($user_id)
{
return $this->db->table(static::TABLE)->eq('user_id', $user_id)->desc('date')->asc('start')->findAll();
}
/**
* Get the timetable for a given user
*
* @access public
* @param integer $user_id User id
* @param string $start_date
* @param string $end_date
* @return array
*/
public function getByUserAndDate($user_id, $start_date, $end_date)
{
return $this->db->table(static::TABLE)
->eq('user_id', $user_id)
->gte('date', $start_date)
->lte('date', $end_date)
->desc('date')
->asc('start')
->findAll();
}
/**
* Add a new time slot in the database
*
* @access public
* @param integer $user_id User id
* @param string $date Day (ISO8601 format)
* @param boolean $all_day All day flag
* @param float $start Start hour (24h format)
* @param float $end End hour (24h format)
* @param string $comment
* @return boolean|integer
*/
public function create($user_id, $date, $all_day, $start = '', $end = '', $comment = '')
{
$values = array(
'user_id' => $user_id,
'date' => $date,
'all_day' => $all_day,
'start' => $all_day ? '' : $start,
'end' => $all_day ? '' : $end,
'comment' => $comment,
);
return $this->persist(static::TABLE, $values);
}
/**
* Remove a specific time slot
*
* @access public
* @param integer $slot_id
* @return boolean
*/
public function remove($slot_id)
{
return $this->db->table(static::TABLE)->eq('id', $slot_id)->remove();
}
/**
* Validate creation
*
* @access public
* @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateCreation(array $values)
{
$v = new Validator($values, array(
new Validators\Required('user_id', t('Field required')),
new Validators\Required('date', t('Field required')),
new Validators\Numeric('all_day', t('This value must be numeric')),
));
return array(
$v->execute(),
$v->getErrors()
);
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Model;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Timetable Workweek
*
* @package model
* @author Frederic Guillot
*/
class TimetableWeek extends Base
{
/**
* SQL table name
*
* @var string
*/
const TABLE = 'timetable_week';
/**
* Get the timetable for a given user
*
* @access public
* @param integer $user_id User id
* @return array
*/
public function getByUser($user_id)
{
return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('day')->asc('start')->findAll();
}
/**
* Add a new time slot in the database
*
* @access public
* @param integer $user_id User id
* @param string $day Day of the week (ISO-8601)
* @param string $start Start hour (24h format)
* @param string $end End hour (24h format)
* @return boolean|integer
*/
public function create($user_id, $day, $start, $end)
{
$values = array(
'user_id' => $user_id,
'day' => $day,
'start' => $start,
'end' => $end,
);
return $this->persist(self::TABLE, $values);
}
/**
* Remove a specific time slot
*
* @access public
* @param integer $slot_id
* @return boolean
*/
public function remove($slot_id)
{
return $this->db->table(self::TABLE)->eq('id', $slot_id)->remove();
}
/**
* Validate creation
*
* @access public
* @param array $values Form values
* @return array $valid, $errors [0] = Success or not, [1] = List of errors
*/
public function validateCreation(array $values)
{
$v = new Validator($values, array(
new Validators\Required('user_id', t('Field required')),
new Validators\Required('day', t('Field required')),
new Validators\Numeric('day', t('This value must be numeric')),
new Validators\Required('start', t('Field required')),
new Validators\Required('end', t('Field required')),
));
return array(
$v->execute(),
$v->getErrors()
);
}
}