From 2a04d497da0a477d56e4e5d94d804ac34d8cbb2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 19 Sep 2017 16:40:55 +0200 Subject: [PATCH] Use a different css into timespent entry page when user is on holiday --- htdocs/core/lib/project.lib.php | 32 ++++--- htdocs/holiday/class/holiday.class.php | 113 ++++++++++++++++++++++--- htdocs/projet/activity/perday.php | 10 ++- htdocs/projet/activity/perweek.php | 23 ++++- 4 files changed, 151 insertions(+), 27 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 8233251d815..2e5799f970c 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -576,10 +576,10 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t * @param string $mine Show only task lines I am assigned to * @param int $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to * @param int $preselectedday Preselected day - * @param boolean $var Var for css of lines + * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon * @return $inc */ -function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask=1, $preselectedday='', $var=false) +function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable) { global $conf, $db, $user, $bc, $langs; global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; @@ -732,8 +732,12 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print $tableCell; print ''; + $cssonholiday=''; + if (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning '; + if (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; + // Duration - print ''; + print ''; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; $alreadyspent=''; @@ -783,8 +787,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); - else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); + if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); + else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); } $level--; } @@ -798,7 +802,6 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr } - /** * Output a task line into a perday intput mode * @@ -812,10 +815,10 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr * @param string $tasksrole Array of roles user has on task * @param string $mine Show only task lines I am assigned to * @param int $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to - * @param boolean $var Var for css of lines + * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon * @return $inc */ -function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask=1, $var=false) +function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable) { global $conf, $db, $user, $bc, $langs; global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; @@ -851,7 +854,6 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Break on a new project if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) { - //$var = ! $var; $lastprojectid=$lines[$i]->fk_project; $projectstatic->id = $lines[$i]->fk_project; } @@ -966,13 +968,18 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ for ($idw = 0; $idw < 7; $idw++) { $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); + + $cssonholiday=''; + if (! $isavailable[$tmpday]['morning']) $cssonholiday.='onholidaymorning '; + if (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon '; + $tmparray=dol_getdate($tmpday); $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; $alreadyspent=''; if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); - $tableCell =''; + $tableCell =''; if ($alreadyspent) { $tableCell.=''; @@ -1008,8 +1015,8 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); - else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); + if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); + else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); } $level--; } @@ -1163,7 +1170,6 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $sql2.= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee"; $sql2.= " ORDER BY p.title, p.ref"; - $var=true; $resql = $db->query($sql2); if ($resql) { diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index ad9ead401dd..10589c9d0b4 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -284,7 +284,7 @@ class Holiday extends CommonObject * @param string $filter SQL Filter * @return int -1 if KO, 1 if OK, 2 if no result */ - function fetchByUser($user_id,$order='',$filter='') + function fetchByUser($user_id, $order='', $filter='') { global $langs, $conf; @@ -692,13 +692,17 @@ class Holiday extends CommonObject } /** - * verifDateHolidayCP + * Check if a user is on holiday (partially or completely) into a period. + * This function can be used to avoid to have 2 leave requests on same period for example. + * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. * * @param int $fk_user Id user - * @param date $dateDebut Start date - * @param date $dateFin End date - * @param int $halfday Tag to define half day when holiday start and end - * @return boolean + * @param date $dateDebut Start date of period to check + * @param date $dateFin End date of period to check + * @param int $halfday Tag to define how start and end the period to check: + * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning + * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. + * @see verifDateHolidayForTimestamp */ function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) { @@ -710,14 +714,103 @@ class Holiday extends CommonObject if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays // TODO Also use halfday for the check - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } + if ($halfday == 0) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == -1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 2) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + else + { + dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP'); + } } return true; + } + + /** + * Check a user is not on holiday for a particular timestamp + * + * @param int $fk_user Id user + * @param timestamp $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) + * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. + * @see verifDateHolidayCP + */ + function verifDateHolidayForTimestamp($fk_user, $timestamp) + { + global $langs, $conf; + + $isavailablemorning=true; + $isavailableafternoon=true; + + $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " AND cp.fk_user = ".(int) $fk_user; + $sql.= " AND date_debut <= '".$this->db->idate($timestamp)."' AND date_fin >= '".$this->db->idate($timestamp)."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon + if ($num_rows > 0) + { + $i=0; + while ($i < $num_rows) + { + $obj = $this->db->fetch_object($resql); + + // Note: $obj->halday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning + $arrayofrecord[$obj->rowid]=array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday); + $i++; + } + + // We found a record, user is on holiday by default, so is not available is true. + $isavailablemorning = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_start'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_start'] && $record['halfday'] == -1) continue; + $isavailablemorning = false; + break; + } + $isavailableafternoon = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_end'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_end'] && $record['halfday'] == 1) continue; + $isavailableafternoon = false; + break; + } + } + } + else dol_print_error($this->db); + + return array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon); } diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index da789675cb8..ad1815c5efc 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -484,10 +485,17 @@ print "\n"; // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +$isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse); // $daytoparse is a date with hours = 0 +$isavailable[$daytoparse]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + if (count($tasksarray) > 0) { $j=0; - projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse); + projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse, $isavailable); $colspan = 8; if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) $colspan++; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index c0482967c9e..caf2a3e4e84 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -474,9 +475,25 @@ print ''.$langs->trans("TimeSpent").'' $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); -for($i=0;$i<7;$i++) +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +for ($i=0;$i<7;$i++) { - print ''.dol_print_date($startday + ($i * 3600 * 24), '%a').'
'.dol_print_date($startday + ($i * 3600 * 24), 'dayreduceformat').''; + $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $i, 'd'); // $firstdaytoshow is a date with hours = 0 + $dayinloop = dol_time_plus_duree($startday, $i, 'd'); + + // Useless because $dayinloopwithouthours should be same than $dayinloopfromfirstdaytoshow + //$tmparray = dol_getdate($dayinloop); + //$dayinloopwithouthours=dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); + //print dol_print_date($dayinloop, 'dayhour').' '; + //print dol_print_date($dayinloopwithouthours, 'dayhour').' '; + //print dol_print_date($dayinloopfromfirstdaytoshow, 'dayhour').'
'; + + $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow); + $isavailable[$dayinloopfromfirstdaytoshow]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
'.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; } print ''; print "\n"; @@ -491,7 +508,7 @@ if (count($tasksarray) > 0) $j=0; $level=0; - projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); + projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable); $colspan=7; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++;