diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 6eb05106686..d198de99b1a 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -1883,7 +1883,7 @@ class ActionComm extends CommonObject $color = 'style="color: #'.$this->type_color.' !important;"'; } if ($this->type_picto) { - $imgpicto = img_picto($titlealt.'rr', $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); + $imgpicto = img_picto($titlealt, $this->type_picto, '', 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); } else { if ($this->type_code == 'AC_RDV') { $imgpicto = img_picto($titlealt, 'meeting', $color, 0, 0, 0, '', ($morecss ? ' '.$morecss : '')); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 93ae98884a3..02737de7db2 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -33,14 +33,13 @@ // Load Dolibarr environment require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (isModEnabled('project')) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -} +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; /** * @var Conf $conf @@ -50,14 +49,7 @@ if (isModEnabled('project')) { * @var User $user */ -if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { - $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW = 3; -} - -if (!getDolGlobalString('AGENDA_EXT_NB')) { - $conf->global->AGENDA_EXT_NB = 5; -} -$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB'); +$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB', 5); $DELAYFORCACHE = 300; // 300 seconds $disabledefaultvalues = GETPOSTINT('disabledefaultvalues'); @@ -122,10 +114,10 @@ $year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"); $month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m"); $week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W"); $day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d"); -$pid = GETPOSTINT("search_projectid", 3) ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); +$pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); -$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW'); +$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW', 3); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $dateselect = dol_mktime(0, 0, 0, GETPOSTINT('dateselectmonth'), GETPOSTINT('dateselectday'), GETPOSTINT('dateselectyear')); @@ -149,7 +141,7 @@ if (is_scalar($actioncode) && $actioncode == '-1') { } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS')); } $defaultview = getDolGlobalString('AGENDA_DEFAULT_VIEW', 'show_month'); // default for app @@ -253,14 +245,14 @@ if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda|DE:Modul_Terminplanung'; -llxHeader('', $langs->trans("Agenda"), $help_url); - $form = new Form($db); $companystatic = new Societe($db); $contactstatic = new Contact($db); $userstatic = new User($db); +$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda|DE:Modul_Terminplanung'; +llxHeader('', $langs->trans("Agenda"), $help_url); + $now = dol_now(); $nowarray = dol_getdate($now); $nowyear = $nowarray['year']; @@ -407,9 +399,13 @@ if ($mode == 'show_day') { //print dol_print_date($firstdaytoshow,'dayhour').' '.dol_print_date($lastdaytoshow,'dayhour'); /*$title = $langs->trans("DoneAndToDoActions"); - if ($status == 'done') $title = $langs->trans("DoneActions"); - if ($status == 'todo') $title = $langs->trans("ToDoActions"); - */ +if ($status == 'done') { + $title = $langs->trans("DoneActions"); +} +if ($status == 'todo') { + $title = $langs->trans("ToDoActions"); +} +*/ $param = ''; if ($actioncode || GETPOSTISSET('search_actioncode')) { @@ -428,10 +424,10 @@ if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { - $param .= "&search_filter=".urlencode($filter); + $param .= "&search_filter=".urlencode((string) $filter); } if ($filtert) { - $param .= "&search_filtert=".urlencode($filtert); + $param .= "&search_filtert=".urlencode((string) $filtert); } if ($usergroup > 0) { $param .= "&search_usergroup=".urlencode((string) ($usergroup)); @@ -771,10 +767,14 @@ if ($resourceid > 0) { } // We must filter on assignment table if ($filtert > 0 || $usergroup > 0) { - $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; -} -if ($usergroup > 0) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar"; + $sql .= " ON ar.fk_actioncomm = a.id AND ar.element_type='user'"; + if ($filtert > 0) { + $sql .= " AND ar.fk_element = ".((int) $filtert); + } + if ($usergroup > 0) { + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element AND ugu.fk_usergroup = ".((int) $usergroup); + } } $sql .= ' WHERE a.fk_action = ca.id'; $sql .= ' AND a.entity IN ('.getEntity('agenda').')'; // bookcal is a "virtual view" of agenda @@ -830,10 +830,6 @@ if ($search_sale && $search_sale != '-1') { if ($socid) { $sql .= " AND a.fk_soc = ".((int) $socid); } -// We must filter on assignment table -if ($filtert > 0 || $usergroup > 0) { - $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; -} //var_dump($day.' '.$month.' '.$year); if ($mode == 'show_day') { $sql .= " AND ("; @@ -866,7 +862,7 @@ if ($status == '0') { // To do (not started) $sql .= " AND a.percent = 0"; } -if ($status == 'na') { +if ($status === 'na') { // Not applicable $sql .= " AND a.percent = -1"; } @@ -902,7 +898,7 @@ if ($search_categ_cus != -1) { } // Sort on date -$sql .= ' ORDER BY datep'; +$sql .= $db->order("datep"); //print $sql; dol_syslog("comm/action/index.php", LOG_DEBUG); @@ -1170,8 +1166,8 @@ if ($user->hasRight("holiday", "read")) { $event->type = 'holiday'; $event->type_picto = 'holiday'; - $event->datep = $db->jdate($obj->date_start) + (empty($halfday) || $halfday == 1 ? 0 : 12 * 60 * 60 - 1); - $event->datef = $db->jdate($obj->date_end) + (empty($halfday) || $halfday == -1 ? 24 : 12) * 60 * 60 - 1; + $event->datep = $db->jdate($obj->date_start) + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12 * 60 * 60 - 1); + $event->datef = $db->jdate($obj->date_end) + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1; $event->date_start_in_calendar = $event->datep; $event->date_end_in_calendar = $event->datef; @@ -1183,24 +1179,50 @@ if ($user->hasRight("holiday", "read")) { $event->percentage = 0; } - if ($obj->halfday == 1) { - $event->label = $obj->lastname.' ('.$langs->trans("Morning").')'; - } elseif ($obj->halfday == -1) { - $event->label = $obj->lastname.' ('.$langs->trans("Afternoon").')'; - } else { - $event->label = $obj->lastname; - } + $event->label = $langs->trans("Holiday"); $daycursor = $event->date_start_in_calendar; $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + $daycursorend = $event->date_end_in_calendar; + $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel'); + $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel'); + $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel'); + + // daykey must be date that represent day box in calendar so must be a user time $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $ifornbofdays = 0; do { - $eventarray[$daykey][] = $event; + $ifornbofdays++; + + $firstdayofholiday = ($ifornbofdays == 1); + $lastdayofholiday = ($daykeygmt == dol_get_first_hour($event->date_end_in_calendar, 'gmt')); + + /* + var_dump(dol_print_date($daykeygmt, 'dayhour', 'gmt')); + var_dump(dol_print_date(dol_get_first_hour($event->date_end_in_calendar, 'gmt'), 'dayhour', 'gmt')); + var_dump($lastdayofholiday); + var_dump($obj->halfday); + */ + + if ((in_array($obj->halfday, array(1, 2)) == 1 && $lastdayofholiday) || (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday)) { + // We create a copy of event because we want tochange the label + $newevent = dol_clone($event, 1); + if (in_array($obj->halfday, array(1, 2)) && $lastdayofholiday) { + $newevent->label .= ' ('.$langs->trans("Morning").')'; + } elseif (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday) { + $newevent->label .= ' ('.$langs->trans("Afternoon").')'; + } + $eventarray[$daykey][] = $newevent; // We need to use ->gtTypePicto, getXXXon object, so clone must be PHP clone. + } else { + $eventarray[$daykey][] = $event; // We can use the event unchanged + } $daykey += 60 * 60 * 24; + $daykeygmt += 60 * 60 * 24; } while ($daykey <= $event->date_end_in_calendar); $i++; @@ -1951,6 +1973,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if (!empty($cacheusers[$event->userownerid]->color)) { $color = $cacheusers[$event->userownerid]->color; } + + /* May be we need this: if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) { + $color = $event->type_color; + }*/ } elseif ($event->type_code == 'ICALEVENT') { // Event come from external ical file $numical++; if (!empty($event->icalname)) { @@ -2092,7 +2118,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa //var_dump($event->userassigned); //var_dump($event->transparency); print ''; + + // First the tr of the event (only one tr for event is used, but several td) print ''; print ''; + // Status - Percent $withstatus = 0; - if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') { + if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') { $withstatus = 1; if ($event->percentage >= 0) { $withstatus = 2; diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index bab2ff5916c..915094db599 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -49,14 +49,12 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; * @var User $user */ -if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { - $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW = 3; -} - -$action = GETPOST('action', 'aZ09'); +$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB', 5); +$DELAYFORCACHE = 300; // 300 seconds $disabledefaultvalues = GETPOSTINT('disabledefaultvalues'); +$check_holiday = GETPOSTINT('check_holiday'); $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOSTINT("search_filtert", 3) ? GETPOSTINT("search_filtert", 3) : GETPOSTINT("filtert", 3); $usergroup = GETPOSTINT("search_usergroup", 3) ? GETPOSTINT("search_usergroup", 3) : GETPOSTINT("usergroup", 3); @@ -64,10 +62,9 @@ $usergroup = GETPOSTINT("search_usergroup", 3) ? GETPOSTINT("search_usergroup", //$showbirthday = empty($conf->use_javascript_ajax)?GETPOST("showbirthday","int"):1; $showbirthday = 0; -// If not choice done on calendar owner, we filter on user. -/*if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) -{ - $filtert = $user->id; +// If no choice done on calendar owner (like on left menu link "Agenda"), we filter on current user by default. +/*if (empty($filtert) && !getDolGlobalString('AGENDA_ALL_CALENDARS')) { + $filtert = (string) $user->id; }*/ $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -85,6 +82,7 @@ if (!$sortfield) { $sortfield = "a.datec"; } +// Security check $socid = GETPOSTINT("search_socid") ? GETPOSTINT("search_socid") : GETPOSTINT("socid"); if ($user->socid) { $socid = $user->socid; @@ -101,19 +99,21 @@ if (!$user->hasRight('agenda', 'allactions', 'read')) { $canedit = 0; } if (!$user->hasRight('agenda', 'allactions', 'read') || $filter == 'mine') { // If no permission to see all, we show only affected to me - $filtert = $user->id; + $filtert = (string) $user->id; } +$action = GETPOST('action', 'aZ09'); + $mode = 'show_peruser'; $resourceid = GETPOSTINT("search_resourceid") ? GETPOSTINT("search_resourceid") : GETPOSTINT("resourceid"); -$year = GETPOSTINT("year") ? GETPOSTINT("year") : idate("Y"); -$month = GETPOSTINT("month") ? GETPOSTINT("month") : idate("m"); -$week = GETPOSTINT("week") ? GETPOSTINT("week") : idate("W"); -$day = GETPOSTINT("day") ? GETPOSTINT("day") : idate("d"); +$year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"); +$month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m"); +$week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W"); +$day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d"); $pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 -$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); -$maxprint = ((GETPOSTINT("maxprint") != '') ? GETPOSTINT("maxprint") : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); +$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW', 3); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $search_categ_cus = GETPOSTINT("search_categ_cus", 3) ? GETPOSTINT("search_categ_cus", 3) : 0; // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) @@ -133,7 +133,7 @@ if ($dateselect > 0) { $year = GETPOSTINT('dateselectyear'); } -$tmp = !getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS') ? '9-18' : $conf->global->MAIN_DEFAULT_WORKING_HOURS; +$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS', '9-18'); $tmp = str_replace(' ', '', $tmp); // FIX 7533 $tmparray = explode('-', $tmp); $begin_h = GETPOSTISSET('begin_h') ? GETPOSTINT('begin_h') : ($tmparray[0] != '' ? $tmparray[0] : 9); @@ -148,7 +148,7 @@ if ($end_h <= $begin_h) { $end_h = $begin_h + 1; } -$tmp = !getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS') ? '1-5' : $conf->global->MAIN_DEFAULT_WORKING_DAYS; +$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS', '1-5'); $tmp = str_replace(' ', '', $tmp); // FIX 7533 $tmparray = explode('-', $tmp); $begin_d = GETPOSTISSET('begin_d') ? GETPOSTINT('begin_d') : ($tmparray[0] != '' ? $tmparray[0] : 1); @@ -164,7 +164,7 @@ if ($end_d < $begin_d) { } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS')); } if (empty($mode) && !GETPOSTISSET('mode')) { @@ -177,12 +177,12 @@ if (GETPOST('viewcal', 'alpha') && $mode != 'show_day' && $mode != 'show_week' & } // View by month if (GETPOST('viewweek', 'alpha') || $mode == 'show_week') { $mode = 'show_week'; - $week = ($week ? $week : idate("W")); - $day = ($day ? $day : idate("d")); + $week = ($week ? $week : date("W")); + $day = ($day ? $day : date("d")); } // View by week if (GETPOST('viewday', 'alpha') || $mode == 'show_day') { $mode = 'show_day'; - $day = ($day ? $day : idate("d")); + $day = ($day ? $day : date("d")); } // View by day $object = new ActionComm($db); @@ -193,7 +193,7 @@ $langs->loadLangs(array('users', 'agenda', 'other', 'commercial')); // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('agenda')); -$result = restrictedArea($user, 'agenda', 0, '', 'myactions'); +$result = restrictedArea($user, 'agenda', 0, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id'); if ($user->socid && $socid) { $result = restrictedArea($user, 'societe', $socid); } @@ -248,9 +248,65 @@ $nowmonth = $nowarray['mon']; $nowday = $nowarray['mday']; -// Define list of all external calendars (global setup) $listofextcals = array(); +// Define list of all external calendars (global setup) +if (!getDolGlobalString('AGENDA_DISABLE_EXT')) { + $i = 0; + while ($i < $MAXAGENDA) { + $i++; + $source = 'AGENDA_EXT_SRC'.$i; + $name = 'AGENDA_EXT_NAME'.$i; + $offsettz = 'AGENDA_EXT_OFFSETTZ'.$i; + $color = 'AGENDA_EXT_COLOR'.$i; + $default = 'AGENDA_EXT_ACTIVEBYDEFAULT'.$i; + $buggedfile = 'AGENDA_EXT_BUGGEDFILE'.$i; + if (getDolGlobalString($source) && getDolGlobalString($name)) { + // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' + $listofextcals[] = array( + 'type' => 'globalsetup', + 'src' => getDolGlobalString($source), + 'name' => dol_string_nohtmltag(getDolGlobalString($name)), + 'offsettz' => (int) getDolGlobalInt($offsettz, 0), + 'color' => dol_string_nohtmltag(getDolGlobalString($color)), + // @phan-suppress-next-line PhanPluginSuspiciousParamPosition + 'default' => dol_string_nohtmltag(getDolGlobalString($default)), + 'buggedfile' => dol_string_nohtmltag(getDolGlobalString('buggedfile', '')) + ); + } + } +} + +// Define list of external calendars (user setup) +if (!getDolUserString('AGENDA_DISABLE_EXT')) { + $i = 0; + while ($i < $MAXAGENDA) { + $i++; + $source = 'AGENDA_EXT_SRC_'.$user->id.'_'.$i; + $name = 'AGENDA_EXT_NAME_'.$user->id.'_'.$i; + $offsettz = 'AGENDA_EXT_OFFSETTZ_'.$user->id.'_'.$i; + $color = 'AGENDA_EXT_COLOR_'.$user->id.'_'.$i; + $enabled = 'AGENDA_EXT_ENABLED_'.$user->id.'_'.$i; + $default = 'AGENDA_EXT_ACTIVEBYDEFAULT_'.$user->id.'_'.$i; + $buggedfile = 'AGENDA_EXT_BUGGEDFILE_'.$user->id.'_'.$i; + + if (getDolUserString($source) && getDolUserString($name)) { + // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' + $listofextcals[] = array( + 'type' => 'usersetup', + 'src' => getDolUserString($source), + 'name' => dol_string_nohtmltag(getDolUserString($name)), + 'offsettz' => (int) (empty($user->conf->$offsettz) ? 0 : $user->conf->$offsettz), + 'color' => dol_string_nohtmltag(getDolUserString($color)), + // @phan-suppress-next-line PhanPluginSuspiciousParamPosition + 'default' => dol_string_nohtmltag(getDolUserString($default)), + 'buggedfile' => dol_string_nohtmltag(isset($user->conf->buggedfile) ? $user->conf->buggedfile : '') + ); + } + } +} + + $prev = dol_get_first_day_week($day, $month, $year); $first_day = $prev['first_day']; $first_month = $prev['first_month']; @@ -264,7 +320,7 @@ $next_year = $next['year']; $next_month = $next['month']; $next_day = $next['day']; -$max_day_in_month = idate("t", dol_mktime(0, 0, 0, $month, 1, $year)); +$max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year)); $tmpday = $first_day; //print 'xx'.$prev_year.'-'.$prev_month.'-'.$prev_day; @@ -296,7 +352,7 @@ if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { - $param .= "&search_filter=".urlencode($filter); + $param .= "&search_filter=".urlencode((string) $filter); } if ($filtert) { $param .= "&search_filtert=".urlencode((string) $filtert); @@ -377,66 +433,31 @@ $nav .= " ".dol_print_date(dol_mktime(0, 0, 0, $first_mo $nav .= " \n"; $nav .= "   trans("Next"))."\">\n"; if (empty($conf->dol_optimize_smallscreen)) { - $nav .= "   '.$langs->trans("Today").' '; + $nav .= '   '.$langs->trans("Today").' '; } $nav .= ''; $nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0); -$nav .= ' '; +//$nav .= ' '; +$nav .= ''; // Must be after the nav definition -$param .= '&year='.urlencode((string) ($year)).'&month='.urlencode((string) ($month)).($day ? '&day='.urlencode((string) ($day)) : ''); +$paramnodate = $param; +$param .= '&year='.$year.'&month='.$month.($day ? '&day='.$day : ''); //print 'x'.$param; -$paramnoaction = preg_replace('/action=[a-z_]+/', '', $param); +$paramnoaction = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $param)); +$paramnoactionodate = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $paramnodate)); $head = calendars_prepare_head($paramnoaction); print ''."\n"; - -$showextcals = $listofextcals; -// Legend -if ($conf->use_javascript_ajax) { - $s = ''; - $s .= ''."\n"; - if (!empty($conf->use_javascript_ajax)) { - $s .= '
'.$langs->trans("LocalAgenda").'  
'; - if (is_array($showextcals) && count($showextcals) > 0) { - foreach ($showextcals as $val) { - $htmlname = md5($val['name']); - $s .= ''."\n"; - $s .= '
'.$val ['name'].'  
'; - } - } - - //$s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; - - // Calendars from hooks - $parameters = array(); - $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); - if (empty($reshook)) { - $s .= $hookmanager->resPrint; - } elseif ($reshook > 1) { - $s = $hookmanager->resPrint; - } - } +if ($optioncss != '') { + print ''; } +print ''; +print ''; + $mode = 'show_peruser'; $massactionbutton = ''; @@ -515,43 +536,135 @@ if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda' $newcardbutton .= dolGetButtonTitle($langs->trans("AddAction"), '', 'fa fa-plus-circle', $urltocreateaction); } -$num = 0; - -print_barre_liste($langs->trans("Agenda"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.''.$newcardbutton, '', $limit, 1, 0, 1, $viewmode); +// Define the legend/list of calendard to show +$s = ''; $link = ''; -//print load_fiche_titre('', $link.'     '.$nav.' '.$newcardbutton, ''); -$s .= "\n".''."\n"; +$showextcals = $listofextcals; +$bookcalcalendars = array(); -// Local calendar -$newtitle = '
'; -$newtitle .= ' '.$langs->trans("LocalAgenda").'   '; -$newtitle .= '
'; -//$newtitle=$langs->trans($title); - -$s = $newtitle; - -// Calendars from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); -if (empty($reshook)) { - $s .= $hookmanager->resPrint; -} elseif ($reshook > 1) { - $s = $hookmanager->resPrint; +// Load Bookcal Calendars +if (isModEnabled("bookcal")) { + $sql = "SELECT ba.rowid, bc.label, bc.ref, bc.rowid as id_cal"; + $sql .= " FROM ".MAIN_DB_PREFIX."bookcal_availabilities as ba"; + $sql .= " JOIN ".MAIN_DB_PREFIX."bookcal_calendar as bc"; + $sql .= " ON bc.rowid = ba.fk_bookcal_calendar"; + $sql .= " WHERE bc.status = 1"; + $sql .= " AND ba.status = 1"; + $sql .= " AND bc.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda + if (!empty($filtert) && $filtert != '-1') { + $sql .= " AND bc.visibility IN (".$db->sanitize($filtert, 0, 0, 0, 0).")"; + } + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $objp = $db->fetch_object($resql); + $label = !empty($objp->label) ? $objp->label : $objp->ref; + $bookcalcalendars["calendars"][] = array("id" => $objp->id_cal, "label" => $label); + $bookcalcalendars["availabilitieslink"][$objp->rowid] = $objp->id_cal; + $i++; + } + } else { + dol_print_error($db); + } } -$s .= "\n".''."\n"; +if (!empty($conf->use_javascript_ajax)) { // If javascript on + $s .= "\n".''."\n"; -print $s; + $s .= ''."\n"; -print '
'; -print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus); -print '
'; + // Local calendar + $s .= '
'; + + // Holiday calendar + if ($user->hasRight("holiday", "read")) { + $s .= ' +
+   +
'; + } + + // External calendars + if (is_array($showextcals) && count($showextcals) > 0) { + foreach ($showextcals as $val) { + $htmlname = md5($val['name']); // not used for security purpose, only to get a string with no special char + + $s .= ''."\n"; + $s .= '
'.$val ['name'].'  
'; + } + } + + // Birthdays + //$s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; + + // Bookcal Calendar + /* + if (isModEnabled("bookcal")) { + if (!empty($bookcalcalendars["calendars"])) { + foreach ($bookcalcalendars["calendars"] as $key => $value) { + $label = $value['label']; + $s .= '
'; + $s .= ''; + $s .= '  
'; + } + } + } + */ + + // Calendars from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); + if (empty($reshook)) { + $s .= $hookmanager->resPrint; + } elseif ($reshook > 1) { + $s = $hookmanager->resPrint; + } + + $s .= "\n".''."\n"; +} else { // If javascript off + $newparam = $param; // newparam is for birthday links + $newparam = preg_replace('/showbirthday=[0-1]/i', 'showbirthday='.(empty($showbirthday) ? 1 : 0), $newparam); + if (!preg_match('/showbirthday=/i', $newparam)) { + $newparam .= '&showbirthday=1'; + } + $link = ''; + if (empty($showbirthday)) { + $link .= $langs->trans("AgendaShowBirthdayEvents"); + } else { + $link .= $langs->trans("AgendaHideBirthdayEvents"); + } + $link .= ''; +} -// Get event in an array +// Load events from database into $eventarray $eventarray = array(); @@ -566,8 +679,14 @@ $sql .= " a.datep2,"; $sql .= " a.percent,"; $sql .= " a.fk_user_author,a.fk_user_action,"; $sql .= " a.transparency, a.priority, a.fulldayevent, a.location,"; -$sql .= " a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,"; -$sql .= " ca.code, ca.libelle as type_label, ca.color, ca.type as type_type, ca.picto as type_picto"; +$sql .= " a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_calendar,"; +$sql .= " a.fk_element, a.elementtype,"; +$sql .= " ca.code as type_code, ca.libelle as type_label, ca.color as type_color, ca.type as type_type, ca.picto as type_picto"; + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as ca, ".MAIN_DB_PREFIX."actioncomm as a"; // We must filter on resource table if ($resourceid > 0) { @@ -586,7 +705,7 @@ if ($filtert > 0 || $usergroup > 0) { } $sql .= " WHERE a.fk_action = ca.id"; -$sql .= " AND a.entity IN (".getEntity('agenda').")"; +$sql .= " AND a.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda // Condition on actioncode if (!empty($actioncode)) { if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) { @@ -624,7 +743,7 @@ if ($pid) { } // If the internal user must only see his customers, force searching by him $search_sale = 0; -if (!$user->hasRight('societe', 'client', 'voir')) { +if (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) { $search_sale = $user->id; } // Search on sale representative @@ -668,6 +787,7 @@ if ($type) { $sql .= " AND ca.id = ".((int) $type); } if ($status == '0') { + // To do (not started) $sql .= " AND a.percent = 0"; } if ($status === 'na') { @@ -684,6 +804,18 @@ if ($status == 'done' || $status == '100') { if ($status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; } +// We must filter on assignment table +if ($filtert > 0 || $usergroup > 0) { + $sql .= " AND ("; + if ($filtert > 0) { + $sql .= "ar.fk_element = ".((int) $filtert); + } + if ($usergroup > 0) { + $sql .= ($filtert > 0 ? " OR " : "")." ugu.fk_usergroup = ".((int) $usergroup); + } + $sql .= ")"; +} + // Search in categories, -1 is all and -2 is no categories if ($search_categ_cus != -1) { if ($search_categ_cus == -2) { @@ -701,13 +833,14 @@ $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); + $MAXONSAMEPAGE = 10000; // Useless to have more. Protection to avoid memory overload when high number of event (for example after a mass import) $i = 0; - while ($i < $num) { + while ($i < $num && $i < $MAXONSAMEPAGE) { $obj = $db->fetch_object($resql); //print $obj->fk_user_action.' '.$obj->id."
"; // Discard auto action if option is on - if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->code == 'AC_OTH_AUTO') { + if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->type_code == 'AC_OTH_AUTO') { $i++; continue; } @@ -718,49 +851,70 @@ if ($resql) { // Create a new object action $event = new ActionComm($db); + $event->id = $obj->id; - $event->datep = $datep; // datep and datef are GMT date - $event->datef = $datep2; - $event->type_code = $obj->code; - $event->type_color = $obj->color; + $event->ref = $event->id; + + $event->fulldayevent = $obj->fulldayevent; + + // event->datep and event->datef must be GMT date. + if ($event->fulldayevent) { + $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); + $event->datep = $db->jdate($obj->datep, $tzforfullday ? 'tzuser' : 'tzserver'); // If saved in $tzforfullday = gmt, we must invert date to be in user tz + $event->datef = $db->jdate($obj->datep2, $tzforfullday ? 'tzuser' : 'tzserver'); + } else { + // Example: $obj->datep = '1970-01-01 01:00:00', jdate will return 0 if TZ of PHP server is Europe/Berlin (+1) + $event->datep = $db->jdate($obj->datep, 'tzserver'); + $event->datef = $db->jdate($obj->datep2, 'tzserver'); + } + //$event->datep_formated_gmt = dol_print_date($event->datep, 'dayhour', 'gmt'); + //var_dump($obj->id.' '.$obj->datep.' '.dol_print_date($obj->datep, 'dayhour', 'gmt')); + //var_dump($obj->id.' '.$event->datep.' '.dol_print_date($event->datep, 'dayhour', 'gmt')); + + $event->type_code = $obj->type_code; + $event->type_label = $obj->type_label; + $event->type_color = $obj->type_color; + $event->type = $obj->type_type; + $event->type_picto = $obj->type_picto; + $event->label = $obj->label; $event->percentage = $obj->percent; $event->authorid = $obj->fk_user_author; // user id of creator $event->userownerid = $obj->fk_user_action; // user id of owner + $event->fetch_userassigned(); // This load $event->userassigned + $event->priority = $obj->priority; - $event->fulldayevent = $obj->fulldayevent; $event->location = $obj->location; $event->transparency = $obj->transparency; + $event->fk_element = $obj->fk_element; + $event->elementid = $obj->fk_element; + $event->elementtype = $obj->elementtype; $event->fk_project = $obj->fk_project; $event->socid = $obj->fk_soc; $event->contact_id = $obj->fk_contact; - - $event->fk_element = $obj->fk_element; - $event->elementid = $obj->fk_element; - $event->elementtype = $obj->elementtype; + $event->fk_bookcal_calendar = $obj->fk_bookcal_calendar; + if (!empty($event->fk_bookcal_calendar)) { + $event->type = "bookcal_calendar"; + } // Defined date_start_in_calendar and date_end_in_calendar property // They are date start and end of action but modified to not be outside calendar view. - $event->date_start_in_calendar = $datep; - if ($datep2 != '' && $datep2 >= $datep) { - $event->date_end_in_calendar = $datep2; + $event->date_start_in_calendar = $event->datep; + if ($event->datef != '' && $event->datef >= $event->datep) { + $event->date_end_in_calendar = $event->datef; } else { - $event->date_end_in_calendar = $datep; + $event->date_end_in_calendar = $event->datep; } //print '
'.$i.' - eventid='.$event->id.' '.dol_print_date($event->date_start_in_calendar, 'dayhour').' '.dol_print_date($firstdaytoshow, 'dayhour').' - '.dol_print_date($event->date_end_in_calendar, 'dayhour').' '.dol_print_date($lastdaytoshow, 'dayhour').'
'."\n"; // Check values - if ($event->date_end_in_calendar < $firstdaytoshow || - $event->date_start_in_calendar >= $lastdaytoshow) { + if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range unset($event); } else { - //print $i.' - eventid='.$event->id.' '.dol_print_date($event->date_start_in_calendar, 'dayhour').' - '.dol_print_date($event->date_end_in_calendar, 'dayhour').'
'."\n"; - $event->fetch_userassigned(); // This load $event->userassigned - if ($event->date_start_in_calendar < $firstdaytoshow) { $event->date_start_in_calendar = $firstdaytoshow; } @@ -773,33 +927,527 @@ if ($resql) { $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); - //print $daycursor.' '.dol_print_date($daycursor, 'dayhour', 'gmt').' '.$event->id.' -> '.$annee.'-'.$mois.'-'.$jour.'
'; + + $daycursorend = $event->date_end_in_calendar; + $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel'); + $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel'); + $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel'); // Loop on each day covered by action to prepare an index to show on calendar $loop = true; $j = 0; - $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz + $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz + /* + print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; + print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; + */ do { - //print 'Add event into eventarray for daykey='.$daykey.'='.dol_print_date($daykey, 'dayhour', 'gmt').' '.$event->id.' '.$event->datep.' '.$event->datef.'
'; + //if ($event->id==408) + //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'
'; + //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'tzuserrel').' - '.dol_print_date($event->datep, 'dayhour', 'tzuserrel').' '.dol_print_date($event->datef, 'dayhour', 'tzuserrel').'
'; $eventarray[$daykey][] = $event; $j++; $daykey += 60 * 60 * 24; - if ($daykey > $event->date_end_in_calendar) { + //if ($daykey > $event->date_end_in_calendar) { + if ($daykey > $daykeyend) { $loop = false; } } while ($loop); - + //var_dump($eventarray); //print 'Event '.$i.' id='.$event->id.' (start='.dol_print_date($event->datep).'-end='.dol_print_date($event->datef); //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array
'; } + + $parameters['obj'] = $obj; + $reshook = $hookmanager->executeHooks('hookEventElements', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks + $event = $hookmanager->resPrint; + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + $i++; } $db->free($resql); } else { dol_print_error($db); } +//var_dump($eventarray); + + +// BIRTHDATES CALENDAR +// Complete $eventarray with birthdates +if ($showbirthday) { + // Add events in array + $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp'; + $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))'; + $sql .= " AND sp.entity IN (".getEntity('contact').")"; + if ($mode == 'show_day') { + $sql .= ' AND MONTH(birthday) = '.((int) $month); + $sql .= ' AND DAY(birthday) = '.((int) $day); + } else { + $sql .= ' AND MONTH(birthday) = '.((int) $month); + } + $sql .= ' ORDER BY birthday'; + + dol_syslog("comm/action/index.php", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $db->fetch_object($resql); + + $event = new ActionComm($db); + + $event->id = $obj->rowid; // We put contact id in action id for birthdays events + $event->ref = $event->id; + + $datebirth = dol_stringtotime($obj->birthday, 1); + //print 'ee'.$obj->birthday.'-'.$datebirth; + $datearray = dol_getdate($datebirth, true); + $event->datep = dol_mktime(0, 0, 0, $datearray['mon'], $datearray['mday'], $year, true); // For full day events, date are also GMT but they won't but converted during output + $event->datef = $event->datep; + + $event->type_code = 'BIRTHDAY'; + $event->type_label = ''; + $event->type_color = ''; + $event->type = 'birthdate'; + $event->type_picto = 'birthdate'; + + $event->label = $langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname, $obj->lastname); + $event->percentage = 100; + $event->fulldayevent = 1; + + $event->contact_id = $obj->rowid; + + $event->date_start_in_calendar = $db->jdate($event->datep); + $event->date_end_in_calendar = $db->jdate($event->datef); + + // Add an entry in eventarray for each day + $daycursor = $event->datep; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + + $eventarray[$daykey][] = $event; + + /*$loop = true; + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee); + do { + $eventarray[$daykey][] = $event; + $daykey += 60 * 60 * 24; + if ($daykey > $event->date_end_in_calendar) $loop = false; + } while ($loop); + */ + $i++; + } + } else { + dol_print_error($db); + } +} + +if ($user->hasRight("holiday", "read")) { + // LEAVE-HOLIDAY CALENDAR + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.statut, x.rowid, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.statut as status"; + $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; + $sql .= " WHERE u.rowid = x.fk_user"; + $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user) + $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved) + + if ($mode == 'show_day') { + // Request only leaves for the current selected day + $sql .= " AND '".$db->escape($year)."-".$db->escape($month)."-".$db->escape($day)."' BETWEEN x.date_debut AND x.date_fin"; // date_debut and date_fin are date without time + } elseif ($mode == 'show_week') { + // Restrict on current month (we get more, but we will filter later) + $sql .= " AND date_debut < '".$db->idate(dol_get_last_day($year, $month))."'"; + $sql .= " AND date_fin >= '".$db->idate(dol_get_first_day($year, $month))."'"; + } elseif ($mode == 'show_month') { + // Restrict on current month + $sql .= " AND date_debut <= '".$db->idate(dol_get_last_day($year, $month))."'"; + $sql .= " AND date_fin >= '".$db->idate(dol_get_first_day($year, $month))."'"; + } + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) { + $obj = $db->fetch_object($resql); + + $event = new ActionComm($db); + + // Need the id of the leave object for link to it + $event->id = $obj->rowid; + $event->ref = $event->id; + + $event->type_code = 'HOLIDAY'; + $event->type_label = ''; + $event->type_color = ''; + $event->type = 'holiday'; + $event->type_picto = 'holiday'; + + $event->datep = $db->jdate($obj->date_start) + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12 * 60 * 60 - 1); + $event->datef = $db->jdate($obj->date_end) + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1; + $event->date_start_in_calendar = $event->datep; + $event->date_end_in_calendar = $event->datef; + + if ($obj->status == 3) { + // Show no symbol for leave with state "leave approved" + $event->percentage = -1; + } elseif ($obj->status == 2) { + // Show TO-DO symbol for leave with state "leave wait for approval" + $event->percentage = 0; + } + + if ($obj->halfday == 1) { + $event->label = $obj->lastname.' ('.$langs->trans("Morning").')'; + } elseif ($obj->halfday == -1) { + $event->label = $obj->lastname.' ('.$langs->trans("Afternoon").')'; + } else { + $event->label = $obj->lastname; + } + + $daycursor = $event->date_start_in_calendar; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + do { + $eventarray[$daykey][] = $event; + + $daykey += 60 * 60 * 24; + } while ($daykey <= $event->date_end_in_calendar); + + $i++; + } + } +} + +// EXTERNAL CALENDAR +// Complete $eventarray with external import Ical +if (count($listofextcals)) { + require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php'; + + foreach ($listofextcals as $key => $extcal) { + $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics + $namecal = $extcal['name']; + $offsettz = $extcal['offsettz']; + $colorcal = $extcal['color']; + $buggedfile = $extcal['buggedfile']; + + $pathforcachefile = dol_sanitizePathName($conf->user->dir_temp).'/'.dol_sanitizeFileName('extcal_'.$namecal.'_user'.$user->id).'.cache'; + //var_dump($pathforcachefile);exit; + + $ical = new ICal(); + $ical->parse($url, $pathforcachefile, $DELAYFORCACHE); + if ($ical->error) { + // Save error message for extcal + $listofextcals[$key]['error'] = $ical->error; + $s .= '
'.dol_escape_htmltag($listofextcals[$key]['name']).': '.$url.'
Error message: '.dol_escape_htmltag($ical->error).'
'; + } + + // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ... + //var_dump($ical->cal); exit; + $icalevents = array(); + if (is_array($ical->get_event_list())) { + $icalevents = array_merge($icalevents, $ical->get_event_list()); // Add $ical->cal['VEVENT'] + } + if (is_array($ical->get_freebusy_list())) { + $icalevents = array_merge($icalevents, $ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY'] + } + + if (count($icalevents) > 0) { + // Duplicate all repeatable events into new entries + $moreicalevents = array(); + foreach ($icalevents as $icalevent) { + if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) { //repeatable event + //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1); + if ($icalevent['DTSTART;VALUE=DATE']) { //fullday event + $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); + $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day + } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) { + $datecurstart = $icalevent['DTSTART']['unixtime']; + $datecurend = $icalevent['DTEND']['unixtime']; + if (!empty($ical->cal['DAYLIGHT']['DTSTART']) && $datecurstart) { + //var_dump($ical->cal); + $tmpcurstart = $datecurstart; + $tmpcurend = $datecurend; + $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART']; + $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART']; + //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']); + // Edit datecurstart and datecurend + if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) { + $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; + } else { + $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; + } + if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) { + $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; + } else { + $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; + } + } + // datecurstart and datecurend are now GMT date + //var_dump($datecurstart); var_dump($datecurend); exit; + } else { + // Not a recognized record + dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR); + continue; + } + //print 'xx'.$datecurstart;exit; + + $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']); + $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1); + $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT']; + if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) { + continue; // We discard repeatable event that end before start date to show + } + if ($datecurstart >= $lastdaytoshow) { + continue; // We discard repeatable event that start after end date to show + } + + $numofevent = 0; + while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) { + if ($datecurend >= $firstdaytoshow) { // We add event + $newevent = $icalevent; + unset($newevent['RRULE']); + if ($icalevent['DTSTART;VALUE=DATE']) { + $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d'); + $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d'); + } else { + $newevent['DTSTART'] = $datecurstart; + $newevent['DTEND'] = $datecurend; + } + $moreicalevents[] = $newevent; + } + // Jump on next occurrence + $numofevent++; + $savdatecurstart = $datecurstart; + if ($icalevent['RRULE']['FREQ'] == 'DAILY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'd'); + } + if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'w'); + } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'm'); + } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') { + $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y'); + $datecurend = dol_time_plus_duree($datecurend, $interval, 'y'); + } + // Test to avoid infinite loop ($datecurstart must increase) + if ($savdatecurstart >= $datecurstart) { + dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR); + $datecurstart += 3600 * 24 * 7; + $datecurend += 3600 * 24 * 7; + } + } + } + } + $icalevents = array_merge($icalevents, $moreicalevents); + + // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray + foreach ($icalevents as $icalevent) { + //var_dump($icalevent); + + //print $icalevent['SUMMARY'].'->'; + //var_dump($icalevent);exit; + if (!empty($icalevent['RRULE'])) { + continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule. + } + + // Create a new object action + $event = new ActionComm($db); + $addevent = false; + if (isset($icalevent['DTSTART;VALUE=DATE'])) { // fullday event + // For full day events, date are also GMT but they won't but converted using tz during output + $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); + if (empty($icalevent['DTEND;VALUE=DATE'])) { + $dateend = $datestart + 86400 - 1; + } else { + $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day + } + //print 'x'.$datestart.'-'.$dateend;exit; + //print dol_print_date($dateend,'dayhour','gmt'); + $event->fulldayevent = 1; + $addevent = true; + } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch) + $datestart = $icalevent['DTSTART']; + $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND']; + + $datestart += +($offsettz * 3600); + $dateend += +($offsettz * 3600); + + $addevent = true; + //var_dump($offsettz); + //var_dump(dol_print_date($datestart, 'dayhour', 'gmt')); + } elseif (isset($icalevent['DTSTART']['unixtime'])) { // File contains a local timezone + a TZ (for example when using bluemind) + $datestart = $icalevent['DTSTART']['unixtime']; + $dateend = $icalevent['DTEND']['unixtime']; + + $datestart += +($offsettz * 3600); + $dateend += +($offsettz * 3600); + + // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight' + if ($buggedfile === 'uselocalandtznodaylight') { // unixtime is a local date that does not take daylight into account, TZID is +1 for example for 'Europe/Paris' in summer instead of 2 + // TODO + } + // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind) + if ($buggedfile === 'uselocalandtzdaylight') { // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer + $localtzs = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTSTART']['TZID'])); + $localtze = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTEND']['TZID'])); + $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs); + $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze); + $tmps = -1 * $localtzs->getOffset($localdts); + $tmpe = -1 * $localtze->getOffset($localdte); + $datestart += $tmps; + $dateend += $tmpe; + //var_dump($datestart); + } + $addevent = true; + } + + if ($addevent) { + $event->id = $icalevent['UID']; + $event->ref = $event->id; + $userId = $userstatic->findUserIdByEmail($namecal); + if (!empty($userId) && $userId > 0) { + $event->userassigned[$userId] = $userId; + $event->percentage = -1; + } + + $event->type_code = "ICALEVENT"; + $event->type_label = $namecal; + $event->type_color = $colorcal; + $event->type = 'icalevent'; + $event->type_picto = 'rss'; + + $event->icalname = $namecal; + $event->icalcolor = $colorcal; + $usertime = 0; // We don't modify date because we want to have date into memory datep and datef stored as GMT date. Compensation will be done during output. + $event->datep = $datestart + $usertime; + $event->datef = $dateend + $usertime; + + if (isset($icalevent['SUMMARY']) && $icalevent['SUMMARY']) { + $event->label = dol_string_nohtmltag($icalevent['SUMMARY']); + } elseif (isset($icalevent['DESCRIPTION']) && $icalevent['DESCRIPTION']) { + $event->label = dol_nl2br(dol_string_nohtmltag($icalevent['DESCRIPTION']), 1); + } else { + $event->label = $langs->trans("ExtSiteNoLabel"); + } + + // Priority (see https://www.kanzaki.com/docs/ical/priority.html) + // LOW = 0 to 4 + // MEDIUM = 5 + // HIGH = 6 to 9 + if (!empty($icalevent['PRIORITY'])) { + $event->priority = $icalevent['PRIORITY']; + } + + // Transparency (see https://www.kanzaki.com/docs/ical/transp.html) + if (!empty($icalevent['TRANSP'])) { + if ($icalevent['TRANSP'] == "TRANSPARENT") { + $event->transparency = 0; // 0 = available / free + } + if ($icalevent['TRANSP'] == "OPAQUE") { + $event->transparency = 1; // 1 = busy + } + + // TODO: MS outlook states + // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free + // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place + // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations + // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy + // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site + } + + if (!empty($icalevent['LOCATION'])) { + $event->location = $icalevent['LOCATION']; + } + + $event->date_start_in_calendar = $event->datep; + + if ($event->datef != '' && $event->datef >= $event->datep) { + $event->date_end_in_calendar = $event->datef; + } else { + $event->date_end_in_calendar = $event->datep; + } + + // Add event into $eventarray if date range are ok. + if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { + //print 'x'.$datestart.'-'.$dateend;exit; + //print 'x'.$datestart.'-'.$dateend;exit; + //print 'x'.$datestart.'-'.$dateend;exit; + // This record is out of visible range + } else { + if ($event->date_start_in_calendar < $firstdaytoshow) { + $event->date_start_in_calendar = $firstdaytoshow; + } + if ($event->date_end_in_calendar >= $lastdaytoshow) { + $event->date_end_in_calendar = ($lastdaytoshow - 1); + } + + // Add an entry in actionarray for each day + $daycursor = $event->date_start_in_calendar; + $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel'); + + // Loop on each day covered by action to prepare an index to show on calendar + $loop = true; + $j = 0; + // daykey must be date that represent day box in calendar so must be a user time + $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); + do { + //if ($event->fulldayevent) print dol_print_date($daykeygmt,'dayhour','gmt').'-'.dol_print_date($daykey,'dayhour','gmt').'-'.dol_print_date($event->date_end_in_calendar,'dayhour','gmt').' '; + $eventarray[$daykey][] = $event; + $daykey += 60 * 60 * 24; + $daykeygmt += 60 * 60 * 24; // Add one day + if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) { + $loop = false; + } + } while ($loop); + } + } + } + } + } +} + +// Complete $eventarray with events coming from external module +$parameters = array(); +$object = null; +$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action); +if (!empty($hookmanager->resArray['eventarray'])) { + foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) { + if (!isset($eventarray[$keyDate])) { + $eventarray[$keyDate] = array(); + } + $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events); + } +} + +// Sort events +foreach ($eventarray as $keyDate => &$dateeventarray) { + usort($dateeventarray, 'sort_events_by_date'); +} + $maxnbofchar = 18; $cachethirdparties = array(); @@ -812,9 +1460,24 @@ if (is_readable($color_file)) { include $color_file; } if (!is_array($theme_datacolor)) { - $theme_datacolor = array(array(120, 130, 150), array(200, 160, 180), array(190, 190, 220)); + $theme_datacolor = array(array(137, 86, 161), array(60, 147, 183), array(250, 190, 80), array(80, 166, 90), array(190, 190, 100), array(91, 115, 247), array(140, 140, 220), array(190, 120, 120), array(115, 125, 150), array(100, 170, 20), array(150, 135, 125), array(85, 135, 150), array(150, 135, 80), array(150, 80, 150)); } +$massactionbutton = ''; + +$num = 0; + +print_barre_liste($langs->trans("Agenda"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.''.$newcardbutton, '', $limit, 1, 0, 1, $viewmode); + +$link = ''; + +// Show div with list of calendars +print $s; + +print '
'; +print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus); +print '
'; + $newparam = $param; // newparam is for birthday links $newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done @@ -1091,6 +1754,7 @@ if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && getDolGlobalString('AGENDA_US } print "\n".''; + print "\n"; // Add js code to manage click on a box @@ -1187,13 +1851,13 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & // We are in a particular day for $username, now we scan all events foreach ($eventarray as $daykey => $notused) { - $annee = dol_print_date($daykey, '%Y', 'tzuserrel'); - $mois = dol_print_date($daykey, '%m', 'tzuserrel'); - $jour = dol_print_date($daykey, '%d', 'tzuserrel'); + $annee = (int) dol_print_date($daykey, '%Y', 'tzuserrel'); + $mois = (int) dol_print_date($daykey, '%m', 'tzuserrel'); + $jour = (int) dol_print_date($daykey, '%d', 'tzuserrel'); //var_dump("daykey=$daykey day=$day jour=$jour, month=$month mois=$mois, year=$year annee=$annee"); - if ($day == $jour && (int) $month == (int) $mois && $year == $annee) { // Is it the day we are looking for when calling function ? + if ($day == $jour && (int) $month == $mois && $year == $annee) { // Is it the day we are looking for when calling function ? //var_dump("day=$day jour=$jour month=$month mois=$mois year=$year annee=$annee"); // Scan all event for this date diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index a3db32f86cb..606ca72fecf 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -924,16 +924,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'; print ''; $daterange = ''; - if ($event->type_code == 'BIRTHDAY') { - // It's birthday calendar - $picb = ''; - //$pice = ''; - //$typea = ($objp->typea == 'birth') ? $picb : $pice; - //var_dump($event); - print $picb.' '.$langs->trans("Birthday").'
'; - //print img_picto($langs->trans("Birthday"), 'birthday-cake').' '; - - $tmpid = $event->id; - - if (empty($cachecontacts[$tmpid])) { - $newcontact = new Contact($db); - $newcontact->fetch($tmpid); - $cachecontacts[$tmpid] = $newcontact; - } - print $cachecontacts[$tmpid]->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline-block'); - - //$event->picto = 'birthday-cake'; - //print $event->getNomUrl(1, $maxnbofchar, 'cal_event', 'birthday', 'contact'); - /*$listofcontacttoshow = ''; - $listofcontacttoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle'); - print $listofcontacttoshow; - */ - } elseif ($event->type_code == 'HOLIDAY') { - // It's holiday calendar - $tmpholiday->fetch($event->id); - - print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block'); - - $tmpid = $tmpholiday->fk_user; - if (empty($cacheusers[$tmpid])) { - $newuser = new User($db); - $newuser->fetch($tmpid); - $cacheusers[$tmpid] = $newuser; - } - - $listofusertoshow = ''; - $listofusertoshow .= '
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block'); - print $listofusertoshow; - } - $parameters = array(); $reshook = $hookmanager->executeHooks('eventOptions', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { @@ -2174,41 +2160,49 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } */ - // Date - if (empty($event->fulldayevent)) { - // Show hours (start ... end) - $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel'); - $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel'); - $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel'); - $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel'); - $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel'); - $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel'); + if ($event->type_code == 'BIRTHDAY') { + // It's birthday calendar + $picb = img_picto('', 'birthday-cake', 'class="pictofixedwidth"'); + print $picb.$langs->trans("Birthday").'
'; + } - // Hour start - if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { - $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel'); - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) { - $daterange .= '-'; + // Date + if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY') { + if (empty($event->fulldayevent)) { + // Show hours (start ... end) + $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel'); + $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel'); + $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel'); + $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel'); + $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel'); + $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel'); + + // Hour start + if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { + $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel'); + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) { + $daterange .= '-'; + } + //else + //print '...'; } - //else - //print '...'; } - } - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) { - $daterange .= '...'; + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) { + $daterange .= '...'; + } } - } - // Hour end - if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { - if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) { - $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel'); + // Hour end + if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { + if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) { + $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel'); + } + } + } else { + if ($showinfo) { + print $langs->trans("EventOnFullDay")."
\n"; } - } - } else { - if ($showinfo) { - print $langs->trans("EventOnFullDay")."
\n"; } } @@ -2216,7 +2210,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $titletoshow = $daterange; $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label); - if ($event->type_code != 'ICALEVENT') { + if ($event->type_code != 'ICALEVENT' && $event->type_code != 'BIRTHDAY') { $savlabel = $event->label; $event->label = $titletoshow; // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. @@ -2242,8 +2236,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $listofusertoshow .= $cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valignmiddle inline-block'); } - print $titletoshow; - print $listofusertoshow.'  '; + if ($event->type_code != 'BIRTHDAY') { + print $titletoshow; + print $listofusertoshow.'  '; + } if ($event->type_code == 'ICALEVENT') { print '
('.dol_trunc($event->icalname, $maxnbofchar).')'; @@ -2263,7 +2259,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $thirdparty = $cachethirdparties[$thirdparty_id]; } if (!empty($thirdparty->id)) { - $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline-block'); + $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large } } if (!empty($contact_id) && $contact_id > 0) { @@ -2278,7 +2274,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $linerelatedto .= ' '; } if (!empty($contact->id)) { - $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline-block'); + $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large } } if (!empty($event->fk_element) && $event->fk_element > 0 && !empty($event->elementtype) && getDolGlobalString('AGENDA_SHOW_LINKED_OBJECT')) { @@ -2296,6 +2292,24 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } } + if ($event->type_code == 'HOLIDAY') { + // It's holiday calendar + $tmpholiday->fetch($event->id); + + //print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block'); + + $tmpid = $tmpholiday->fk_user; + if (empty($cacheusers[$tmpid])) { + $newuser = new User($db); + $newuser->fetch($tmpid); + $cacheusers[$tmpid] = $newuser; + } + + $listofusertoshow = ''; + $listofusertoshow .= "\n".'
'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block')."\n"; + print $listofusertoshow; + } + // Show location if ($showinfo) { if ($event->location) { @@ -2305,9 +2319,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } print '
'; // Date To Birth - print ''; - print '
'; + print '
'; $form = new Form($db); if ($object->birthday) { print $form->selectDate($object->birthday, 'birthday', 0, 0, 0, "perso", 1, 0); } else { print $form->selectDate('', 'birthday', 0, 0, 1, "perso", 1, 0); } - print ': '; + print '   '; if (!empty($object->birthday_alert)) { print ''; } else { diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index cfe0f519db9..de0d14ebd49 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -246,7 +246,7 @@ $holidaystatic = new Holiday($db); // Update sold $result = $object->updateBalance(); -$title = $langs->trans('CPTitreMenu'); +$title = $langs->trans('Holidays'); $help_url = 'EN:Module_Holiday'; llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'bodyforlist mod-holiday page-list'); @@ -542,9 +542,6 @@ if ($id > 0) { // For user tab print ''; } else { - $title = $langs->trans("ListeCP"); - - $newcardbutton = ''; $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition')); diff --git a/htdocs/langs/fr_FR/holiday.lang b/htdocs/langs/fr_FR/holiday.lang index 859f6d0d00a..7c9c40ea112 100644 --- a/htdocs/langs/fr_FR/holiday.lang +++ b/htdocs/langs/fr_FR/holiday.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - holiday HRM=GRH Holidays=Congés -Holiday=Demande de congés +Holiday=Congés CPTitreMenu=Demande de congés MenuReportMonth=État mensuel MenuAddCP=Créer demande de congés