dolibarr 25.0.0-alpha
agenda.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2008-2014 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2022-2026 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 * or see https://www.gnu.org/
21 */
22
55 $form,
56 $canedit,
57 $status,
58 $year,
59 $month,
60 $day,
61 $showbirthday,
62 $filtera,
63 $filtert,
64 $filtered,
65 $pid,
66 $socid,
67 $action,
68 $showextcals = array(),
69 $actioncode = '',
70 $usergroupid = 0,
71 $excludetype = '',
72 $resourceid = 0,
73 $search_categ_cus = 0,
74 $search_import_key = ''
75) {
76 global $user, $langs, $db, $hookmanager;
77 global $massaction;
78
79 $langs->load("companies");
80
81 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
82 $formactions = new FormActions($db);
83
84 // Filters
85 print '<input type="hidden" name="token" value="'.newToken().'">';
86 print '<input type="hidden" name="year" value="'.((int) $year).'">';
87 print '<input type="hidden" name="month" value="'.((int) $month).'">';
88 print '<input type="hidden" name="day" value="'.((int) $day).'">';
89 if ($massaction != 'predelete' && $massaction != 'preaffecttag') { // When $massaction == 'predelete', action may be already output to 'delete' by the mass action system.
90 print '<input type="hidden" name="action" value="'.$action.'">';
91 }
92 print '<input type="hidden" name="search_showbirthday" value="'.((int) $showbirthday).'">';
93
94 print '<div class="divsearchfield">';
95 // Type
96 $multiselect = 0;
97 if (getDolGlobalString('MAIN_ENABLE_MULTISELECT_TYPE')) { // We use an option here because it adds bugs when used on agenda page "peruser" and "list"
98 $multiselect = (getDolGlobalString('AGENDA_USE_EVENT_TYPE'));
99 }
100 print img_picto($langs->trans("ActionType"), 'square', 'class="pictofixedwidth inline-block" style="color: #ddd;"');
101 print $formactions->select_type_actions($actioncode, "search_actioncode", $excludetype, (getDolGlobalString('AGENDA_USE_EVENT_TYPE') ? -1 : 1), 0, $multiselect, 0, 'minwidth150 maxwidth200 widthcentpercentminusx', 1);
102 print '</div>';
103
104 if ($canedit) {
105 // Assigned to user
106 print '<div class="divsearchfield">';
107 print img_picto($langs->trans("ActionsToDoBy"), 'user', 'class="pictofixedwidth inline-block"');
108 print $form->select_dolusers($filtert, 'search_filtert', 1, null, (int) !$canedit, '', '', '0', 0, 0, '', 2, '', 'minwidth100 maxwidth250 widthcentpercentminusx');
109 print '</div>';
110
111 // Assigned to user group
112 print '<div class="divsearchfield">';
113 print img_picto($langs->trans("ToUserOfGroup"), 'object_group', 'class="pictofixedwidth inline-block"');
114 print $form->select_dolgroups($usergroupid, 'usergroup', 1, '', (int) !$canedit, '', array(), '0', false, 'minwidth100 maxwidth250 widthcentpercentminusx');
115 print '</div>';
116
117 if (isModEnabled('resource')) {
118 include_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
119 $formresource = new FormResource($db);
120
121 // Resource
122 print '<div class="divsearchfield">';
123 print img_picto($langs->trans("Resource"), 'object_resource', 'class="pictofixedwidth inline-block"');
124 print $formresource->select_resource_list($resourceid, "search_resourceid", '', 1, 0, 0, [], '', 2, 0, 'minwidth100 maxwidth250 widthcentpercentminusx');
125 print '</div>';
126 }
127 }
128
129 if (isModEnabled('societe') && $user->hasRight('societe', 'lire')) {
130 print '<div class="divsearchfield">';
131 print img_picto($langs->trans("ThirdParty"), 'company', 'class="pictofixedwidth inline-block"');
132 print $form->select_company($socid, 'search_socid', '', '&nbsp;', 0, 0, array(), 0, 'minwidth100 maxwidth250 widthcentpercentminusx');
133 print '</div>';
134 }
135
136 if (isModEnabled('project') && $user->hasRight('projet', 'lire')) {
137 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
138 $formproject = new FormProjets($db);
139
140 print '<div class="divsearchfield">';
141 print img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth inline-block"');
142 print $formproject->select_projects($socid ? $socid : -1, (string) $pid, 'search_projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'minwidth100 maxwidth250 widthcentpercentminusx');
143 print '</div>';
144 }
145
146 if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
147 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
148 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
149 $formother = new FormOther($db);
150 $langs->load('categories');
151
152 print '<div class="divsearchfield">';
153 print img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"');
154 print $formother->select_categories('actioncomm', $search_categ_cus, 'search_categ_cus', 1, $langs->trans('Categories'), 'minwidth100 maxwidth250 widthcentpercentminusx');
155 print '</div>';
156 }
157
158 if ($canedit && !preg_match('/list/', $_SERVER["PHP_SELF"])) {
159 // Status
160 print '<div class="divsearchfield">';
161 print img_picto($langs->trans("Status"), 'status', 'class="pictofixedwidth inline-block"');
162 $formactions->form_select_status_action('formaction', $status, 1, 'search_status', 1, 2, 'minwidth100');
163 print '</div>';
164 }
165
166 // Hooks
167 $parameters = array('canedit' => $canedit, 'pid' => $pid, 'socid' => $socid);
168 $object = null; // Null on purpose: @phan-suppress-next-line PhanPluginConstantVariableNull
169 $reshook = $hookmanager->executeHooks('searchAgendaFrom', $parameters, $object, $action); // Note that $action and $object may have been
170
171 print '<div class="clearboth"></div>';
172}
173
174
181function show_array_actions_to_do($max = 5)
182{
183 global $langs, $conf, $user, $db, $socid;
184
185 $now = dol_now();
186
187 include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
188 include_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
189
190 $sql = "SELECT a.id, a.label, a.datep as dp, a.datep2 as dp2, a.fk_user_author, a.percent";
191 $sql .= ", c.code, c.libelle as type_label";
192 $sql .= ", s.rowid as socid, s.nom as name, s.name_alias";
193 $sql .= ", s.code_client, s.code_compta, s.client";
194 $sql .= ", s.logo, s.email, s.entity";
195 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a LEFT JOIN ";
196 $sql .= " ".MAIN_DB_PREFIX."c_actioncomm as c ON c.id = a.fk_action";
197 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid";
198 if (!$user->hasRight('societe', 'client', 'voir')) {
199 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
200 }
201 $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
202 $sql .= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep2 > '".$db->idate($now)."'))";
203 if (!$user->hasRight('societe', 'client', 'voir')) {
204 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
205 }
206 if ($socid) {
207 $sql .= " AND s.rowid = ".((int) $socid);
208 }
209 $sql .= " ORDER BY a.datep DESC, a.id DESC";
210 $sql .= $db->plimit($max, 0);
211
212 $resql = $db->query($sql);
213 if ($resql) {
214 $num = $db->num_rows($resql);
215
216 print '<div class="div-table-responsive-no-min">';
217 print '<table class="noborder centpercent">';
218 print '<tr class="liste_titre"><th colspan="2">'.$langs->trans("LastActionsToDo", $max).'</th>';
219 print '<th colspan="2" class="right"><a class="commonlink" href="'.dolBuildUrl(DOL_URL_ROOT.'/comm/action/list.php', ['mode' => 'show_list', 'status' => 'todo']).'">'.$langs->trans("FullList").'</a></th>';
220 print '</tr>';
221
222 $i = 0;
223
224 $staticaction = new ActionComm($db);
225 $customerstatic = new Client($db);
226
227 while ($i < $num) {
228 $obj = $db->fetch_object($resql);
229
230
231 print '<tr class="oddeven">';
232
233 $staticaction->type_code = $obj->code;
234 $staticaction->label = ($obj->label ? $obj->label : $obj->type_label);
235 $staticaction->id = $obj->id;
236 print '<td>'.$staticaction->getNomUrl(1, 34).'</td>';
237
238 // print '<td>'.dol_trunc($obj->label,22).'</td>';
239
240 print '<td>';
241 if ($obj->socid > 0) {
242 $customerstatic->id = $obj->socid;
243 $customerstatic->name = $obj->name;
244 //$customerstatic->name_alias = $obj->name_alias;
245 $customerstatic->code_client = $obj->code_client;
246 $customerstatic->code_compta = $obj->code_compta;
247 $customerstatic->code_compta_client = $obj->code_compta;
248 $customerstatic->client = $obj->client;
249 $customerstatic->logo = $obj->logo;
250 $customerstatic->email = $obj->email;
251 $customerstatic->entity = $obj->entity;
252 print $customerstatic->getNomUrl(1, '', 40);
253 }
254 print '</td>';
255
256 $datep = $db->jdate($obj->dp);
257 $datep2 = $db->jdate($obj->dp2);
258
259 // Date
260 print '<td width="100" class="right tddate">'.dol_print_date($datep, 'day').'&nbsp;';
261 $late = 0;
262 if ($obj->percent == 0 && $datep && $datep < dol_now()) {
263 $late = 1;
264 }
265 if ($obj->percent == 0 && !$datep && $datep2 && $datep2 < dol_now()) {
266 $late = 1;
267 }
268 if ($obj->percent > 0 && $obj->percent < 100 && $datep2 && $datep2 < dol_now()) {
269 $late = 1;
270 }
271 if ($obj->percent > 0 && $obj->percent < 100 && !$datep2 && $datep && $datep < dol_now()) {
272 $late = 1;
273 }
274 if ($late) {
275 print img_warning($langs->trans("Late"));
276 }
277 print "</td>";
278
279 // Statut
280 print '<td class="right" width="14">'.$staticaction->LibStatut($obj->percent, 3)."</td>\n";
281
282 print "</tr>\n";
283
284 $i++;
285 }
286 print "</table></div><br>";
287
288 $db->free($resql);
289 } else {
290 dol_print_error($db);
291 }
292}
293
294
302{
303 global $langs, $conf, $user, $db, $socid;
304
305 $now = dol_now();
306
307 $sql = "SELECT a.id, a.percent, a.datep as da, a.datep2 as da2, a.fk_user_author, a.label";
308 $sql .= ", c.code, c.libelle";
309 $sql .= ", s.rowid as socid, s.nom as name, s.name_alias";
310 $sql .= ", s.code_client, s.code_compta, s.client";
311 $sql .= ", s.logo, s.email, s.entity";
312 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a LEFT JOIN ";
313 $sql .= " ".MAIN_DB_PREFIX."c_actioncomm as c ON c.id = a.fk_action ";
314 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid";
315 if (!$user->hasRight('societe', 'client', 'voir')) {
316 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
317 }
318 $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
319 $sql .= " AND (a.percent >= 100 OR (a.percent = -1 AND a.datep2 <= '".$db->idate($now)."'))";
320 if (!$user->hasRight('societe', 'client', 'voir')) {
321 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
322 }
323 if ($socid) {
324 $sql .= " AND s.rowid = ".((int) $socid);
325 }
326 $sql .= " ORDER BY a.datep2 DESC";
327 $sql .= $db->plimit($max, 0);
328
329 $resql = $db->query($sql);
330 if ($resql) {
331 $num = $db->num_rows($resql);
332
333 print '<div class="div-table-responsive-no-min">';
334 print '<table class="noborder centpercent">';
335 print '<tr class="liste_titre"><th colspan="2">'.$langs->trans("LastDoneTasks", $max).'</th>';
336 print '<th colspan="2" class="right"><a class="commonlink" href="'.dolBuildUrl(DOL_URL_ROOT.'/comm/action/list.php', ['mode'=> 'show_list', 'status' => 'done']).'">'.$langs->trans("FullList").'</a></th>';
337 print '</tr>';
338
339 $i = 0;
340
341 $staticaction = new ActionComm($db);
342 $customerstatic = new Societe($db);
343
344 while ($i < $num) {
345 $obj = $db->fetch_object($resql);
346
347
348 print '<tr class="oddeven">';
349
350 $staticaction->type_code = $obj->code;
351 $staticaction->label = $obj->label;
352 $staticaction->id = $obj->id;
353 print '<td>'.$staticaction->getNomUrl(1, 34).'</td>';
354
355 //print '<td>'.dol_trunc($obj->label,24).'</td>';
356
357 print '<td>';
358 if ($obj->socid > 0) {
359 $customerstatic->id = $obj->socid;
360 $customerstatic->name = $obj->name;
361 //$customerstatic->name_alias = $obj->name_alias;
362 $customerstatic->code_client = $obj->code_client;
363 $customerstatic->code_compta = $obj->code_compta;
364 $customerstatic->code_compta_client = $obj->code_compta;
365 $customerstatic->client = $obj->client;
366 $customerstatic->logo = $obj->logo;
367 $customerstatic->email = $obj->email;
368 $customerstatic->entity = $obj->entity;
369 print $customerstatic->getNomUrl(1, '', 30);
370 }
371 print '</td>';
372
373 // Date
374 print '<td width="100" class="right tddate">'.dol_print_date($db->jdate($obj->da2), 'day');
375 print "</td>";
376
377 // Status
378 print '<td class="right" width="14">'.$staticaction->LibStatut($obj->percent, 3)."</td>\n";
379
380 print "</tr>\n";
381 $i++;
382 }
383 // TODO Add a reminder for "contracts need to be put in service."
384 // TODO Add reminder for "contracts expiring soon."
385 print "</table></div><br>";
386
387 $db->free($resql);
388 } else {
389 dol_print_error($db);
390 }
391}
392
393
400{
401 global $langs, $conf, $user, $extrafields;
402
403 $extrafields->fetch_name_optionals_label('actioncomm');
404
405 $h = 0;
406 $head = array();
407
408 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/admin/agenda_other.php");
409 $head[$h][1] = $langs->trans("Miscellaneous");
410 $head[$h][2] = 'other';
411 $h++;
412
413 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/admin/agenda.php");
414 $head[$h][1] = $langs->trans("AutoActions");
415 $head[$h][2] = 'autoactions';
416 $h++;
417
418 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/admin/agenda_reminder.php");
419 $head[$h][1] = $langs->trans("Reminders");
420 $head[$h][2] = 'reminders';
421 $h++;
422
423 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/admin/agenda_xcal.php");
424 $head[$h][1] = $langs->trans("ExportCal");
425 $head[$h][2] = 'xcal';
426 $h++;
427
428 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT."/admin/agenda_extsites.php");
429 $head[$h][1] = $langs->trans("ExtSites");
430 $head[$h][2] = 'extsites';
431 $h++;
432
433 complete_head_from_modules($conf, $langs, null, $head, $h, 'agenda_admin');
434
435 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/admin/extrafields.php', array('elementtype' => 'agenda'));
436 $head[$h][1] = $langs->trans("ExtraFields");
437 $nbExtrafields = $extrafields->attributes['actioncomm']['count'];
438 if ($nbExtrafields > 0) {
439 $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
440 }
441 $head[$h][2] = 'attributes';
442 $h++;
443
444 complete_head_from_modules($conf, $langs, null, $head, $h, 'agenda_admin', 'remove');
445
446
447 return $head;
448}
449
457{
458 global $db, $langs, $conf, $user;
459
460 $h = 0;
461 $head = array();
462
463 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/card.php', ['id'=> $object->id]);
464 $head[$h][1] = $langs->trans("CardAction");
465 $head[$h][2] = 'card';
466 $h++;
467
468 // Tab to link resources
469 if (isModEnabled('resource')) {
470 include_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
471 $resource = new Dolresource($db);
472
473 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/resource/element_resource.php', ['element' => 'action', 'element_id'=> $object->id]);
474 $listofresourcelinked = $resource->getElementResources($object->element, $object->id);
475 $nbResources = (is_array($listofresourcelinked) ? count($listofresourcelinked) : 0);
476 $head[$h][1] = $langs->trans("Resources");
477 if ($nbResources > 0) {
478 $head[$h][1] .= (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') ? '<span class="badge marginleftonlyshort">'.($nbResources).'</span>' : '');
479 }
480 $head[$h][2] = 'resources';
481 $h++;
482 }
483
484 // Attached files
485 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
486 require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
487 $upload_dir = $conf->agenda->dir_output."/".$object->id;
488 $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
489 $nbLinks = Link::count($db, $object->element, $object->id);
490 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/document.php', ['id' => $object->id]);
491 $head[$h][1] = $langs->trans("Documents");
492 if (($nbFiles + $nbLinks) > 0) {
493 $head[$h][1] .= (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') ? '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>' : '');
494 }
495 $head[$h][2] = 'documents';
496 $h++;
497
498 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/info.php', ['id' => $object->id]);
499 $head[$h][1] = $langs->trans('Info');
500 $head[$h][2] = 'info';
501 $h++;
502
503 complete_head_from_modules($conf, $langs, $object, $head, $h, 'action');
504
505 complete_head_from_modules($conf, $langs, $object, $head, $h, 'action', 'remove');
506
507 return $head;
508}
509
510
518{
519 global $langs, $conf, $user;
520
521 $h = 0;
522 $head = array();
523 $query = [];
524 parse_str($param, $query);
525
526 $query = array_merge($query, ['mode' => 'show_list']);
527 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/list.php', $query);
528 $head[$h][1] = $langs->trans("ViewList");
529 $head[$h][2] = 'cardlist';
530 $h++;
531
532 $query['mode'] = 'show_month';
533 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/index.php', $query);
534 $head[$h][1] = $langs->trans("ViewCal");
535 $head[$h][2] = 'cardmonth';
536 $h++;
537
538 $query['mode'] = 'show_week';
539 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/index.php', $query);
540 $head[$h][1] = $langs->trans("ViewWeek");
541 $head[$h][2] = 'cardweek';
542 $h++;
543
544 $query['mode'] = 'show_day';
545 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/index.php', $query);
546 $head[$h][1] = $langs->trans("ViewDay");
547 $head[$h][2] = 'cardday';
548 $h++;
549
550 unset($query['mode']);
551 if (getDolGlobalString('AGENDA_SHOW_PERTYPE')) {
552 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/pertype.php', $query);
553 $head[$h][1] = $langs->trans("ViewPerType");
554 $head[$h][2] = 'cardpertype';
555 $h++;
556 }
557
558 $newparam = $param;
559 $newparam = preg_replace('/&?search_filtert=\d+/', '', $newparam);
560 $query = [];
561 parse_str($newparam, $query);
562
563 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/comm/action/peruser.php', $query);
564 $head[$h][1] = $langs->trans("ViewPerUser");
565 $head[$h][2] = 'cardperuser';
566 $h++;
567
568
569 // Show more tabs from modules
570 // Entries must be declared in modules descriptor with line
571 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
572 // $this->tabs = array('entity:-tabname); to remove a tab
573 complete_head_from_modules($conf, $langs, null, $head, $h, 'agenda');
574
575 complete_head_from_modules($conf, $langs, null, $head, $h, 'agenda', 'remove');
576
577 return $head;
578}
579
599function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventarray, $maxprint = 0, $maxnbofchar = 16, $newparam = '', $showinfo = 0, $minheight = 60, $nonew = 0, $bookcalcalendarsarray = array())
600{
601 global $user, $conf, $langs;
602 global $action, $mode, $filter, $filtert, $status, $actioncode, $usergroup; // Filters used into search form
603 global $theme_datacolor;
604 global $cachethirdparties, $cachecontacts, $cacheusers, $colorindexused;
605 global $hookmanager;
606
607 '@phan-var-force array{0:array{0:int,1:int,2:int},1:array{0:int,1:int,2:int},2:array{0:int,1:int,2:int},3:array{0:int,1:int,2:int}} $theme_datacolor
608 @phan-var-force User[] $cacheusers
609 @phan-var-force array<int<0,3>> $colorindexused';
616 if ($conf->use_javascript_ajax) { // Enable the "Show more button..."
617 $conf->global->MAIN_JS_SWITCH_AGENDA = 1;
618 }
619
620 $dateint = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
621 $datenowint = dol_print_date(dol_now(), "%Y%m%d");
622 //print 'show_day_events day='.$day.' month='.$month.' year='.$year.' dateint='.$dateint.' datenowint='.$datenowint;
623
624 print "\n";
625
626 $curtime = dol_mktime(0, 0, 0, $month, $day, $year);
627 $urltoshow = DOL_URL_ROOT.'/comm/action/index.php?mode=show_day&day='.str_pad((string) $day, 2, "0", STR_PAD_LEFT).'&month='.str_pad((string) $month, 2, "0", STR_PAD_LEFT).'&year='.$year.$newparam;
628 $urltocreate = '';
629 if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
630 $newparam .= '&month='.str_pad((string) $month, 2, "0", STR_PAD_LEFT).'&year='.$year;
631 $hourminsec = getDolGlobalString('AGENDA_DEFAULT_BEGIN_TIME');
632 if (empty($hourminsec) || !preg_match('/^[0-9]{6}$/', $hourminsec)) {
633 $hourminsec = '100000';
634 }
635 $urltocreate = DOL_URL_ROOT.'/comm/action/card.php?action=create&datep='.sprintf("%04d%02d%02d", $year, $month, $day).$hourminsec.'&backtopage='.urlencode($_SERVER["PHP_SELF"].($newparam ? '?'.$newparam : ''));
636 }
637
638 // Line with title of day
639 print '<div id="dayevent_'.$dateint.'" class="dayevent tagtable centpercent nobordernopadding">'."\n";
640
641 if ($nonew <= 0) {
642 print '<div class="tagtr cursorpointer" onclick="window.location=\''.$urltocreate.'\';"><div class="nowrap tagtd"><div class="left inline-block">';
643 print '<a class="dayevent-aday" style="color: #666" href="'.$urltoshow.'">';
644 print($datenowint == $dateint ? '<span class="badgeliketopmenu">' : '');
645 if ($showinfo) {
646 print dol_print_date($curtime, 'daytextshort');
647 } else {
648 print dol_print_date($curtime, '%d');
649 }
650 print($datenowint == $dateint ? '</span>' : '');
651 print '</a>';
652 print '</div><div class="nowrap floatright inline-block marginrightonly">';
653 if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
654 print '<a class="cursoradd" href="'.$urltocreate.'">'; // Explicit link, useful for nojs interfaces
655 print img_picto($langs->trans("NewAction"), 'edit_add.png');
656 print '</a>';
657 }
658 print '</div></div></div>'."\n";
659 }
660
661 if ($nonew < 0) {
662 print '</div>';
663 return;
664 }
665
666 // Line with td contains all div of each events
667 print '<div class="tagtr">';
668 print '<div class="tagtd centpercent agendacell sortable">';
669
670 //$curtime = dol_mktime (0, 0, 0, $month, $day, $year);
671 $i = 0;
672 $ireallyshown = 0;
673 $itoshow = 0;
674 $numother = 0;
675 $numbirthday = 0;
676 $numical = 0;
677 $numicals = array();
678 $ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
679
680 $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0
681 $nextindextouse = is_array($colorindexused) ? count($colorindexused) : 0; // At first run this is 0, so fist user has 0, next 1, ...
682 //var_dump($colorindexused);
683
684 include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
685 $tmpholiday = new Holiday($db);
686
687 foreach ($eventarray as $daykey => $notused) { // daykey is the 'YYYYMMDD' to show according to user
688 $annee = (int) dol_print_date($daykey, '%Y', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
689 $mois = (int) dol_print_date($daykey, '%m', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
690 $jour = (int) dol_print_date($daykey, '%d', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
691
692 //print 'event daykey='.$daykey.' dol_print_date(daykey)='.dol_print_date($daykey, 'dayhour', 'gmt').' jour='.$jour.' mois='.$mois.' annee='.$annee."<br>\n";
693 //print 'event daykey='.$daykey.' dol_print_date(daykey)='.dol_print_date($daykey, 'dayhour', 'gmt').' day='.$day.' month='.$month.' year='.$year."<br>\n";
694
695 if ($day == $jour && $month == $mois && $year == $annee) {
696 foreach ($eventarray[$daykey] as $index => $event) {
697 if ($i < $maxprint || $maxprint == 0 || getDolGlobalString('MAIN_JS_SWITCH_AGENDA')) {
698 $keysofuserassigned = array_keys($event->userassigned);
699
700 // Define $color (Hex string like '0088FF') and $cssclass of event
701 $color = -1;
702 $cssclass = '';
703 $colorindex = -1;
704 if (in_array($user->id, $keysofuserassigned)) {
705 $cssclass = 'family_mytasks';
706
707 if (empty($cacheusers[$event->userownerid])) {
708 $newuser = new User($db);
709 $newuser->fetch($event->userownerid);
710 $cacheusers[$event->userownerid] = $newuser;
711 }
712 //var_dump($cacheusers[$event->userownerid]->color);
713
714 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
715 if (!empty($cacheusers[$event->userownerid]->color)) {
716 $color = $cacheusers[$event->userownerid]->color;
717 }
718
719 /* May be we need this: if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
720 $color = $event->type_color;
721 }*/
722 } elseif ($event->type_code == 'ICALEVENT') { // Event come from external ical file
723 $numical++;
724 if (!empty($event->icalname)) {
725 if (!isset($numicals[dol_string_nospecial($event->icalname)])) {
726 $numicals[dol_string_nospecial($event->icalname)] = 0;
727 }
728 $numicals[dol_string_nospecial($event->icalname)]++;
729 }
730
731 $color = ($event->icalcolor ? $event->icalcolor : -1);
732 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
733 } elseif ($event->type_code == 'BIRTHDAY') {
734 $numbirthday++;
735 $colorindex = 2;
736 $cssclass = 'family_birthday ';
737 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
738 } elseif ($event->type == 'bookcal_calendar') {
739 $numbirthday++;
740 $colorindex = 3;
741 $cssclass = 'family_bookcal_calendar_'.(!empty($bookcalcalendarsarray["availabilitieslink"]) ? $bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar] : "");
742 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
743 } else {
744 $numother++;
745 $color = ($event->icalcolor ? $event->icalcolor : -1);
746 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
747
748 if (empty($cacheusers[$event->userownerid])) {
749 $newuser = new User($db);
750 $newuser->fetch($event->userownerid);
751 $cacheusers[$event->userownerid] = $newuser;
752 }
753 //var_dump($cacheusers[$event->userownerid]->color);
754
755 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
756 if (!empty($cacheusers[$event->userownerid]->color)) {
757 $color = $cacheusers[$event->userownerid]->color;
758 }
759 }
760
761 if ($color < 0) { // Color was not set on user card. Set color according to color index.
762 // Define color index if not yet defined
763 $idusertouse = ($event->userownerid ? $event->userownerid : 0);
764 if (isset($colorindexused[$idusertouse])) {
765 $colorindex = $colorindexused[$idusertouse]; // Color already assigned to this user
766 } else {
767 $colorindex = $nextindextouse;
768 $colorindexused[$idusertouse] = $colorindex;
769 if (!empty($theme_datacolor[$nextindextouse + 1])) {
770 $nextindextouse++; // Prepare to use next color
771 }
772 }
773 if (isset($theme_datacolor[$colorindex])) {
774 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
775 } elseif (getDolGlobalString('THEME_ELDY_BACKBODY')) {
776 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
777 $color = colorArrayToHex(colorStringToArray(getDolGlobalString('THEME_ELDY_BACKBODY'), array()), '');
778 } else {
779 $color = "ffffff";
780 }
781 }
782 $cssclass = $cssclass.' eventday_'.$ymd;
783
784 // Defined style to disable drag and drop feature
785 if ($event->type_code == 'AC_OTH_AUTO') {
786 $cssclass .= " unmovable";
787 } elseif ($event->type_code == 'HOLIDAY') {
788 $cssclass .= " unmovable";
789 } elseif ($event->type_code == 'BIRTHDAY') {
790 $cssclass .= " unmovable";
791 } elseif ($event->type_code == 'ICALEVENT') {
792 $cssclass .= " unmovable";
793 } elseif (dol_print_date($event->datep, '%Y%m%d', 'tzuserrel') != sprintf("%04d%02d%02d", $annee, $mois, $jour)) {
794 // The event is shown on a day that is not its real start day (it is on several days, maybe
795 // starting before the displayed range). A drop sets the start to the drop day, so only its
796 // real start day can be dragged.
797 $cssclass .= " unmovable unmovable-mustusefirstdaytodrag";
798 } else {
799 if ($user->hasRight('agenda', 'allactions', 'create') ||
800 (($event->authorid == $user->id || $event->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
801 $cssclass .= " movable cursormove";
802 } else {
803 $cssclass .= " unmovable";
804 }
805 }
806
807 $h = '';
808 $nowrapontd = 1;
809 if ($mode == 'show_day') {
810 $h = 'height: 100%; ';
811 $nowrapontd = 0;
812 }
813 if ($mode == 'show_week') {
814 $h = 'height: 100%; ';
815 $nowrapontd = 0;
816 }
817
818 // Show event box
819 print "\n";
820 print '<!-- start event '.$i.' -->'."\n";
821
822 $morecss = '';
823 if ($maxprint && $ireallyshown >= $maxprint) {
824 $morecss = 'showifmore';
825 }
826 if ($event->type == 'birthdate' && !GETPOST('check_birthday')) {
827 $morecss = 'hidden';
828 }
829 if ($event->type == 'holiday' && !GETPOST('check_holiday')) {
830 $morecss = 'hidden';
831 }
832 /* I comment this because it hides event recorded from bookcal online page
833 if ($event->type == 'bookcal_calendar' && !GETPOST('check_bookcal_calendar_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar])) {
834 $morecss = 'hidden';
835 } */
836 if ($morecss != 'hidden') {
837 $itoshow++;
838 }
839 if ($morecss != 'showifmore' && $morecss != 'hidden') {
840 $ireallyshown++;
841 }
842
843 //var_dump($event->type.' - '.$morecss.' - '.$cssclass.' - '.$i.' - '.$ireallyshown.' - '.$itoshow);
844 if (isModEnabled("bookcal") && $event->type == 'bookcal_calendar') {
845 print '<div id="event_'.$ymd.'_'.$i.'" class="event family_'.$event->type.'_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar].' '.$cssclass.($morecss ? ' '.$morecss : '').'"';
846 } else {
847 print '<div id="event_'.$ymd.'_'.$i.'" class="event family_'.$event->type.' '.$cssclass.($morecss ? ' '.$morecss : '').'"';
848 }
849 //print ' style="height: 100px;';
850 //print ' position: absolute; top: 40px; width: 50%;';
851 //print '"';
852 print '>';
853
854 //var_dump($event->userassigned);
855 //var_dump($event->transparency);
856 print '<table class="centpercent cal_event';
857 print(empty($event->transparency) ? ' cal_event_notbusy' : ' cal_event_busy');
858 //if (empty($event->transparency) && empty($conf->global->AGENDA_NO_TRANSPARENT_ON_NOT_BUSY)) print ' opacitymedium'; // Not busy
859 print '" style="'.$h;
860 $colortouse = $color;
861 // If colortouse is similar than background, we force to change it.
862 if (empty($event->transparency) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
863 print 'background: #f0f0f0;';
864 print 'border-left: 5px solid #'.$colortouse.';';
865 } else {
866 print 'background: #f0f0f0;';
867 print 'border-left: 5px solid #'.dol_color_minus($colortouse, -3).';';
868 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($colortouse, -3).'), to(#'.dol_color_minus($colortouse, -1).'));';
869 }
870 //print 'background: #'.$colortouse.';';
871 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -3).'), to(#'.dol_color_minus($color, -1).'));';
872 //if (!empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));';
873 //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;';
874 //print ' -moz-border-radius:4px;"';
875 //print 'border: 1px solid #ccc" width="100%"';
876 print '">';
877
878 // First the tr of the event (only one tr for event is used, but several td)
879 print '<tr>';
880 print '<td class="tdoverflow nobottom small centpercent '.($nowrapontd ? 'nowrap ' : '').'cal_event'.($event->type_code == 'BIRTHDAY' ? ' cal_event_birthday' : '').'">';
881 print '<!-- left section of event -->';
882
883 $daterange = '';
884
885 $parameters = array();
886 $reshook = $hookmanager->executeHooks('eventOptions', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
887 if ($reshook < 0) {
888 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
889 } else {
890 '@phan-var-force ActionComm $event';
891 if (empty($reshook)) {
892 // Other calendar
893 /*
894 if (empty($event->fulldayevent)) {
895 //print $event->getNomUrl(2).' ';
896 }
897 */
898
899 if ($event->type_code == 'BIRTHDAY') {
900 // It's birthday calendar
901 $picb = img_picto('', 'birthday-cake', 'class="pictofixedwidth"');
902 print $picb.$langs->trans("Birthday").'<br>';
903 }
904
905 // Date
906 if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY') {
907 if (empty($event->fulldayevent)) {
908 // Show hours (start ... end)
909 $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel');
910 $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel');
911 $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel');
912 $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel');
913 $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel');
914 $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel');
915
916 // Hour start
917 if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) {
918 $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel');
919 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
920 if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) {
921 $daterange .= '-';
922 }
923 //else
924 //print '...';
925 }
926 }
927 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
928 if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) {
929 $daterange .= '...';
930 }
931 }
932 // Hour end
933 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
934 if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) {
935 $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
936 }
937 }
938 } else {
939 if ($showinfo) {
940 print $langs->trans("EventOnFullDay")."<br>\n";
941 }
942 }
943 }
944
945 // Show title
946 $titletoshow = $daterange;
947 $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label);
948
949 if ($event->type_code != 'ICALEVENT' && $event->type_code != 'BIRTHDAY') {
950 $savlabel = $event->label;
951 $event->label = $titletoshow;
952 // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user.
953 $titletoshow = (($event->type_picto || $event->type_code) ? $event->getTypePicto() : '');
954 $titletoshow .= $event->getNomUrl(0, $maxnbofchar, 'cal_event cal_event_title valignmiddle', '', 0, 0); // do not add 'inline-block' in css here: it makes the title transformed completely into '...'
955 $event->label = $savlabel;
956 }
957
958 // Loop on each assigned user
959 $listofusertoshow = '';
960 $posuserassigned = 0;
961 foreach ($event->userassigned as $tmpid => $tmpdata) {
962 if (!$posuserassigned && $titletoshow) {
963 $listofusertoshow .= '<br>';
964 }
965 $posuserassigned++;
966 if (empty($cacheusers[$tmpid])) {
967 $newuser = new User($db);
968 $newuser->fetch($tmpid);
969 $cacheusers[$tmpid] = $newuser;
970 }
971
972 $listofusertoshow .= $cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valignmiddle inline-block');
973 }
974
975 if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'HOLIDAY') {
976 print $titletoshow;
977 print $listofusertoshow.' &nbsp;';
978 }
979
980 if ($event->type_code == 'ICALEVENT') {
981 print '<br>('.dol_trunc($event->icalname, $maxnbofchar).')';
982 }
983
984 $thirdparty_id = ($event->socid > 0 ? $event->socid : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0));
985 $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0));
986
987 // If action related to company / contact
988 $linerelatedto = '';
989 if ($thirdparty_id > 0) {
990 if (!isset($cachethirdparties[$thirdparty_id]) || !is_object($cachethirdparties[$thirdparty_id])) {
991 $thirdparty = new Societe($db);
992 $thirdparty->fetch($thirdparty_id);
993 $cachethirdparties[$thirdparty_id] = $thirdparty;
994 } else {
995 $thirdparty = $cachethirdparties[$thirdparty_id];
996 }
997 if (!empty($thirdparty->id)) {
998 $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large
999 }
1000 }
1001 if (!empty($contact_id) && $contact_id > 0) {
1002 if (empty($cachecontacts[$contact_id]) || !is_object($cachecontacts[$contact_id])) {
1003 $contact = new Contact($db);
1004 $contact->fetch($contact_id);
1005 $cachecontacts[$contact_id] = $contact;
1006 } else {
1007 $contact = $cachecontacts[$contact_id];
1008 }
1009 if ($linerelatedto) {
1010 $linerelatedto .= '&nbsp;';
1011 }
1012 if (!empty($contact->id)) {
1013 $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large
1014 }
1015 }
1016 if (!empty($event->fk_element) && $event->fk_element > 0 && !empty($event->elementtype) && getDolGlobalString('AGENDA_SHOW_LINKED_OBJECT')) {
1017 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1018 if ($linerelatedto) {
1019 $linerelatedto .= '<br>';
1020 }
1021 $linerelatedto .= dolGetElementUrl($event->fk_element, $event->elementtype, 1);
1022 }
1023 if ($linerelatedto) {
1024 print ' '.$linerelatedto;
1025 }
1026 } elseif (!empty($reshook)) {
1027 print $hookmanager->resPrint;
1028 }
1029 }
1030
1031 if ($event->type_code == 'HOLIDAY') {
1032 // It's holiday calendar
1033 $tmpholiday->fetch($event->id);
1034
1035 print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block');
1036
1037 $tmpid = $tmpholiday->fk_user;
1038 if (empty($cacheusers[$tmpid])) {
1039 $newuser = new User($db);
1040 $newuser->fetch($tmpid);
1041 $cacheusers[$tmpid] = $newuser;
1042 }
1043
1044 $listofusertoshow = '';
1045 $listofusertoshow .= "\n".'<br>'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block')."\n";
1046 print $listofusertoshow;
1047 }
1048
1049 // Show location
1050 if ($showinfo) {
1051 if ($event->location) {
1052 print '<br>';
1053 print $langs->trans("Location").': '.$event->location;
1054 }
1055 }
1056
1057 print '</td>';
1058
1059 // Status - Percent
1060 $withstatus = 0;
1061 if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') {
1062 $withstatus = 1;
1063 if ($event->percentage >= 0) {
1064 $withstatus = 2;
1065 }
1066 }
1067 print '<td class="nobottom right nowrap cal_event_right'.($withstatus >= 2 ? ' cal_event_right_status' : '').'">';
1068 if ($withstatus) {
1069 print $event->getLibStatut(3, 1);
1070 } else {
1071 print '&nbsp;';
1072 }
1073 print '</td></tr></table>';
1074 print '</div><!-- end event '.$i.' -->'."\n";
1075
1076 $i++;
1077 } else {
1078 print '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?mode='.$mode.'&maxprint=0&month='.((int) $monthshown).'&year='.((int) $year);
1079 print($status ? '&status='.$status : '').($filter ? '&filter='.urlencode($filter) : '');
1080 print($filtert ? '&search_filtert='.urlencode((string) $filtert) : '');
1081 print($usergroup ? '&search_usergroup='.urlencode((string) $usergroup) : '');
1082 print($actioncode != '' ? '&search_actioncode='.urlencode($actioncode) : '');
1083 print '">'.img_picto("all", "1downarrow_selected.png").' ...';
1084 print ' +'.(count($eventarray[$daykey]) - $maxprint);
1085 print '</a>';
1086 break;
1087 //$ok=false; // To avoid to show twice the link
1088 }
1089 }
1090
1091 break;
1092 }
1093 }
1094 if (!$i) { // No events
1095 print '&nbsp;';
1096 }
1097
1098 if (getDolGlobalString('MAIN_JS_SWITCH_AGENDA') && $itoshow > $ireallyshown && $maxprint) {
1099 print '<div class="center cursorpointer cal_showmore" id="more_'.$ymd.'">'.img_picto("All", "angle-double-down", 'class="warning"').' +'.($itoshow - $ireallyshown).'</div>';
1100 //print ' +'.(count($eventarray[$daykey])-$maxprint);
1101
1102 print '<script type="text/javascript">'."\n";
1103 print 'jQuery(document).ready(function () {'."\n";
1104 print ' var open=0;'."\n";
1105 print ' jQuery("#more_'.$ymd.'").click(function() { console.log("Click on showmore for '.$ymd.'"); reinit_day_'.$ymd.'(); event.stopImmediatePropagation(); });'."\n";
1106 print ' function reinit_day_'.$ymd.'() {'."\n";
1107 print ' jQuery(".eventday_'.$ymd.'.showifmore").toggle();'."\n";
1108 print ' open = open + 1; if (open > 1) { open = 0; }'."\n";
1109 print ' if (open) { ';
1110 print ' jQuery("#more_'.$ymd.'").html(\''.img_picto("All", "angle-double-up", 'class="warning"').'\');'."\n";
1111 print ' } else { ';
1112 print ' jQuery("#more_'.$ymd.'").html(\''.img_picto("All", "angle-double-down", 'class="warning"').' +'.($itoshow - $ireallyshown).'\');'."\n";
1113 print ' }'."\n";
1114 print ' }'."\n";
1115 print '});'."\n";
1116 print '</script>'."\n";
1117 }
1118
1119 print '</div></div>'; // td tr
1120
1121 print '</div>'; // table
1122 print "\n";
1123}
1124
1125
1134function dol_color_minus($color, $minus, $minusunit = 16)
1135{
1136 $newcolor = $color;
1137 if ($minusunit == 16 && is_array($newcolor)) {
1138 $newcolor[0] = dechex(max(min(hexdec($newcolor[0]) - $minus, 15), 0));
1139 $newcolor[2] = dechex(max(min(hexdec($newcolor[2]) - $minus, 15), 0));
1140 $newcolor[4] = dechex(max(min(hexdec($newcolor[4]) - $minus, 15), 0));
1141 } else {
1142 // Not yet implemented
1143 }
1144 return $newcolor;
1145}
1146
1167function agenda_build_eventarray($db, $hookmanager, $user, &$object, &$action, $mode, $year, $month, $day, $firstdaytoshow, $lastdaytoshow, $filters, $sincedatec = null)
1168{
1169 $usergroup = $filters['usergroup'];
1170 $filtert = $filters['filtert'];
1171 $resourceid = $filters['resourceid'];
1172 $actioncode = $filters['actioncode'];
1173 $pid = $filters['pid'];
1174 $socid = $filters['socid'];
1175 $type = $filters['type'];
1176 $status = $filters['status'];
1177 $search_categ_cus = $filters['search_categ_cus'];
1178
1179 // Load events from database into $eventarray
1180 $eventarray = array();
1181 $nbevents = 0;
1182
1183 // DEFAULT CALENDAR + AUTOEVENT CALENDAR + CONFERENCEBOOTH CALENDAR
1184 $sql = 'SELECT ';
1185 if ($usergroup > 0) {
1186 $sql .= " DISTINCT";
1187 }
1188 $sql .= ' a.id, a.label,';
1189 $sql .= ' a.datep,';
1190 $sql .= ' a.datep2,';
1191 $sql .= ' a.percent,';
1192 $sql .= ' a.fk_user_author,a.fk_user_action,';
1193 $sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,';
1194 $sql .= ' a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_calendar,';
1195 $sql .= ' a.fk_element, a.elementtype,';
1196 $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';
1197
1198 // Add fields from hooks
1199 $parameters = array();
1200 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1201 $sql .= $hookmanager->resPrint;
1202
1203 $sqlfields = $sql; // $sql fields to remove for count total
1204
1205 $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as ca, ".MAIN_DB_PREFIX."actioncomm as a";
1206
1207 // We must filter on assignment table
1208 if (($filtert != '-1' && $filtert != '-2') || $usergroup > 0) {
1209 // TODO Replace with a AND EXISTS
1210 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar ON ar.fk_actioncomm = a.id AND ar.element_type = 'user'";
1211 if ($filtert != '-1' && $filtert != '-2' && $filtert != '-3') {
1212 $sql .= " AND (ar.fk_element IN (".$db->sanitize($filtert).") OR (ar.fk_element IS NULL AND a.fk_user_action = ".((int) $filtert)."))"; // The OR is for backward compatibility
1213 } elseif ($filtert == '-3') {
1214 $sql .= " AND ar.fk_element IN (".$db->sanitize(implode(',', $user->getAllChildIds(1))).")";
1215 }
1216 if ($usergroup > 0) {
1217 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element AND ugu.fk_usergroup = ".((int) $usergroup);
1218 }
1219 }
1220
1221 // We must filter on resource table
1222 if ($resourceid > 0) {
1223 $sql .= ", ".MAIN_DB_PREFIX."element_resources as r";
1224 }
1225
1226 // Add table from hooks
1227 $parameters = array();
1228 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1229 $sql .= $hookmanager->resPrint;
1230
1231 $sql .= " WHERE a.fk_action = ca.id";
1232 $sql .= " AND a.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda
1233 // Condition on actioncode
1234 if (!empty($actioncode)) {
1235 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1236 if ((is_array($actioncode) && in_array('AC_NON_AUTO', $actioncode)) || $actioncode == 'AC_NON_AUTO') {
1237 $sql .= " AND ca.type != 'systemauto'";
1238 } elseif ((is_array($actioncode) && in_array('AC_ALL_AUTO', $actioncode)) || $actioncode == 'AC_ALL_AUTO') {
1239 $sql .= " AND ca.type = 'systemauto'";
1240 } else {
1241 if ((is_array($actioncode) && in_array('AC_OTH', $actioncode)) || $actioncode == 'AC_OTH') {
1242 $sql .= " AND ca.type != 'systemauto'";
1243 }
1244 if ((is_array($actioncode) && in_array('AC_OTH_AUTO', $actioncode)) || $actioncode == 'AC_OTH_AUTO') {
1245 $sql .= " AND ca.type = 'systemauto'";
1246 }
1247 }
1248 } else {
1249 if ((is_array($actioncode) && in_array('AC_NON_AUTO', $actioncode)) || $actioncode === 'AC_NON_AUTO') {
1250 $sql .= " AND ca.type != 'systemauto'";
1251 } elseif ((is_array($actioncode) && in_array('AC_ALL_AUTO', $actioncode)) || $actioncode === 'AC_ALL_AUTO') {
1252 $sql .= " AND ca.type = 'systemauto'";
1253 } else {
1254 if (is_array($actioncode)) {
1255 // Remove all -1 values
1256 $actioncode = array_filter(
1257 $actioncode,
1262 function ($value) {
1263 return ((string) $value !== '-1');
1264 }
1265 );
1266 if (count($actioncode)) {
1267 $sql .= " AND ca.code IN (".$db->sanitize("'".implode("','", $actioncode)."'", 1).")";
1268 }
1269 } elseif ($actioncode !== '-1') {
1270 $sql .= " AND ca.code IN (".$db->sanitize("'".implode("','", explode(',', $actioncode))."'", 1).")";
1271 }
1272 }
1273 }
1274 }
1275 if ($resourceid > 0) {
1276 $sql .= " AND r.element_type = 'action' AND r.element_id = a.id AND r.resource_id = ".((int) $resourceid);
1277 }
1278 if ($pid) {
1279 $sql .= " AND a.fk_project=".((int) $pid);
1280 }
1281 // If the internal user must only see his customers, force searching by him
1282 $search_sale = 0;
1283 if (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) {
1284 $search_sale = $user->id;
1285 }
1286 // Search on sale representative
1287 if ($search_sale && $search_sale != '-1') {
1288 if ($search_sale == -2) {
1289 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc)";
1290 } elseif ($search_sale > 0) {
1291 $sql .= " AND (a.fk_soc IS NULL OR EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc AND sc.fk_user = ".((int) $search_sale)."))";
1292 }
1293 }
1294 // Search on socid
1295 if ($socid > 0) {
1296 $sql .= " AND a.fk_soc = ".((int) $socid);
1297 }
1298 //var_dump($day.' '.$month.' '.$year);
1299 if ($mode == 'show_day') {
1300 $sql .= " AND (";
1301 $sql .= " (a.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
1302 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
1303 $sql .= " OR ";
1304 $sql .= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
1305 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
1306 $sql .= " OR ";
1307 $sql .= " (a.datep < '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
1308 $sql .= " AND a.datep2 > '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
1309 $sql .= ')';
1310 } else {
1311 // To limit array
1312 $sql .= " AND (";
1313 $sql .= " (a.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'"; // Start 7 days before
1314 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')"; // End 7 days after + 3 to go from 28 to 31
1315 $sql .= " OR ";
1316 $sql .= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'";
1317 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')";
1318 $sql .= " OR ";
1319 $sql .= " (a.datep < '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'";
1320 $sql .= " AND a.datep2 > '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')";
1321 $sql .= ')';
1322 }
1323 if ($sincedatec !== null) {
1324 $sql .= " AND (a.datec > '".$db->idate($sincedatec)."' OR a.tms > '".$db->idate($sincedatec)."')";
1325 }
1326 if ($type) {
1327 $sql .= " AND ca.id = ".((int) $type);
1328 }
1329 if ($status == '0') {
1330 // To do (not started)
1331 $sql .= " AND a.percent = 0";
1332 }
1333 if ($status === 'na') {
1334 // Not applicable
1335 $sql .= " AND a.percent = -1";
1336 }
1337 if ($status == '50') {
1338 // Running already started
1339 $sql .= " AND (a.percent > 0 AND a.percent < 100)";
1340 }
1341 if ($status == 'done' || $status == '100') {
1342 $sql .= " AND (a.percent = 100)";
1343 }
1344 if ($status == 'todo') {
1345 $sql .= " AND (a.percent >= 0 AND a.percent < 100)";
1346 }
1347
1348 // Search in categories, -1 is all and -2 is no categories
1349 if ($search_categ_cus != -1) {
1350 if ($search_categ_cus == -2) {
1351 $sql .= " AND NOT EXISTS (SELECT ca.fk_actioncomm FROM ".MAIN_DB_PREFIX."categorie_actioncomm as ca WHERE ca.fk_actioncomm = a.id)";
1352 } elseif ($search_categ_cus > 0) {
1353 $sql .= " AND EXISTS (SELECT ca.fk_actioncomm FROM ".MAIN_DB_PREFIX."categorie_actioncomm as ca WHERE ca.fk_actioncomm = a.id AND ca.fk_categorie IN (".$db->sanitize((string) $search_categ_cus)."))";
1354 }
1355 }
1356
1357 // Sort on date
1358 $sql .= $db->order("datep");
1359
1360 $MAXONSAMEPAGE = getDolGlobalInt('AGENDA_MAX_ON_SAME_PAGE', 5000); // Useless to have more. Protection to avoid memory overload when high number of event (for example after a mass import)
1361
1362 $sql .= $db->plimit($MAXONSAMEPAGE + 1);
1363
1364 dol_syslog("agenda_build_eventarray", LOG_DEBUG);
1365
1366 $resql = $db->query($sql);
1367 if ($resql) {
1368 $num = $db->num_rows($resql);
1369 $nbevents += $num;
1370
1371 $i = 0;
1372 while ($i < $num && $i < $MAXONSAMEPAGE) {
1373 $obj = $db->fetch_object($resql);
1374
1375 // Discard auto action if option is on
1376 if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->type_code == 'AC_OTH_AUTO') {
1377 $i++;
1378 continue;
1379 }
1380
1381 // Create a new object action
1382 $event = new ActionComm($db);
1383
1384 $event->id = $obj->id;
1385 $event->ref = (string) $event->id;
1386
1387 $event->fulldayevent = $obj->fulldayevent;
1388
1389 // event->datep and event->datef must be GMT date.
1390 if ($event->fulldayevent) {
1391 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
1392 $event->datep = $db->jdate($obj->datep, $tzforfullday ? 'tzuser' : 'tzserver'); // If saved in $tzforfullday = gmt, we must invert date to be in user tz
1393 $event->datef = $db->jdate($obj->datep2, $tzforfullday ? 'tzuser' : 'tzserver');
1394 } else {
1395 // Example: $obj->datep = '1970-01-01 01:00:00', jdate will return 0 if TZ of PHP server is Europe/Berlin (+1)
1396 $event->datep = $db->jdate($obj->datep, 'tzserver');
1397 $event->datef = $db->jdate($obj->datep2, 'tzserver');
1398 }
1399 //$event->datep_formated_gmt = dol_print_date($event->datep, 'dayhour', 'gmt');
1400 //var_dump($obj->id.' '.$obj->datep.' '.dol_print_date($obj->datep, 'dayhour', 'gmt'));
1401 //var_dump($obj->id.' '.$event->datep.' '.dol_print_date($event->datep, 'dayhour', 'gmt'));
1402
1403 $event->type_code = $obj->type_code;
1404 $event->type_label = $obj->type_label;
1405 $event->type_color = $obj->type_color;
1406 $event->type = $obj->type_type;
1407 $event->type_picto = $obj->type_picto;
1408
1409 $event->label = $obj->label;
1410 $event->percentage = $obj->percent;
1411
1412 $event->authorid = $obj->fk_user_author; // user id of creator
1413 $event->userownerid = $obj->fk_user_action; // user id of owner
1414 $event->fetch_userassigned(); // This load $event->userassigned
1415
1416 $event->priority = $obj->priority;
1417 $event->location = $obj->location;
1418 $event->transparency = $obj->transparency;
1419 $event->fk_element = $obj->fk_element;
1420 $event->elementid = $obj->fk_element;
1421 $event->elementtype = $obj->elementtype;
1422
1423 $event->fk_project = $obj->fk_project;
1424
1425 $event->socid = $obj->fk_soc;
1426 $event->contact_id = $obj->fk_contact;
1427 $event->fk_bookcal_calendar = $obj->fk_bookcal_calendar;
1428 if (!empty($event->fk_bookcal_calendar)) {
1429 $event->type = "bookcal_calendar";
1430 }
1431
1432 // Defined date_start_in_calendar and date_end_in_calendar property
1433 // They are date start and end of action but modified to not be outside calendar view.
1434 $event->date_start_in_calendar = $event->datep;
1435 if ($event->datef != '' && $event->datef >= $event->datep) {
1436 $event->date_end_in_calendar = $event->datef;
1437 } else {
1438 $event->date_end_in_calendar = $event->datep;
1439 }
1440
1441 // Check values
1442 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) {
1443 // This record is out of visible range
1444 } else {
1445 if ($event->date_start_in_calendar < $firstdaytoshow) {
1446 $event->date_start_in_calendar = $firstdaytoshow;
1447 }
1448 if ($event->date_end_in_calendar >= $lastdaytoshow) {
1449 $event->date_end_in_calendar = ($lastdaytoshow - 1);
1450 }
1451
1452 // Add an entry in actionarray for each day
1453 $daycursor = $event->date_start_in_calendar;
1454 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1455 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1456 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1457
1458 $daycursorend = $event->date_end_in_calendar;
1459 $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel');
1460 $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel');
1461 $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel');
1462
1463 //var_dump(dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt')); // Hour at greenwich
1464 //var_dump($annee.'-'.$mois.'-'.$jour);
1465 //print 'annee='.$annee.' mois='.$mois.' jour='.$jour.'<br>';
1466
1467 // Loop on each day covered by action to prepare an index to show on calendar
1468 $loop = true;
1469 $j = 0;
1470 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz
1471 $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz
1472 /*
1473 print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'<br>';
1474 print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'<br>';
1475 print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'<br>';
1476 print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'<br>';
1477 print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'<br>';
1478 print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'<br>';
1479 */
1480 do {
1481 //if ($event->id==408)
1482 //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').'<br>';
1483 //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').'<br>';
1484
1485 $eventarray[$daykey][] = $event;
1486 $j++;
1487
1488 $daykey += 60 * 60 * 24;
1489 //if ($daykey > $event->date_end_in_calendar) {
1490 if ($daykey > $daykeyend) {
1491 $loop = false;
1492 }
1493 } while ($loop);
1494 //var_dump($eventarray);
1495 //print 'Event '.$i.' id='.$event->id.' (start='.dol_print_date($event->datep).'-end='.dol_print_date($event->datef);
1496 //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<br>';
1497 }
1498
1499 $parameters['obj'] = $obj;
1500 $reshook = $hookmanager->executeHooks('hookEventElements', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
1501 $event = $hookmanager->resPrint;
1502 if ($reshook < 0) {
1503 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1504 }
1505
1506 $i++;
1507 }
1508 } else {
1509 dol_print_error($db);
1510 }
1511 //var_dump($eventarray);
1512
1513 return array('eventarray' => $eventarray, 'nbevents' => $nbevents, 'maxonsamepage' => $MAXONSAMEPAGE);
1514}
1515
1533function agenda_get_birthday_events($db, $langs, $user, $mode, $month, $day, $year, &$eventarray, &$nbevents, $firstdaytoshow, $lastdaytoshow)
1534{
1535 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1536
1537 // Build the map of month => year for the displayed period so we can load birthdays
1538 // for all months covered by the view. A week or a month grid can span two or three months,
1539 // and a week at a year boundary can even span two years, so we cannot rely on the reference
1540 // $month/$year only.
1541 $birthdaymonthyearmap = array();
1542 $tmpstamp = $firstdaytoshow;
1543 $i = 0;
1544 while ($tmpstamp < $lastdaytoshow && $i < 1000) { // 1000 is a protection against infinite loops
1545 $m = (int) dol_print_date($tmpstamp, '%m', 'tzuserrel');
1546 if (!isset($birthdaymonthyearmap[$m])) {
1547 $birthdaymonthyearmap[$m] = (int) dol_print_date($tmpstamp, '%Y', 'tzuserrel');
1548 }
1549 $tmpstamp = dol_time_plus_duree($tmpstamp, 1, 'd');
1550 $i++;
1551 }
1552
1553
1554 $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday';
1555 $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp';
1556 $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))';
1557 $sql .= " AND sp.entity IN (".getEntity('contact').")";
1558 if ($mode == 'show_day') {
1559 $sql .= ' AND MONTH(birthday) = '.((int) $month);
1560 $sql .= ' AND DAY(birthday) = '.((int) $day);
1561 } else {
1562 // Load birthdays for all months covered by the displayed period (week or month grid)
1563 $sql .= ' AND MONTH(birthday) IN ('.$db->sanitize(implode(',', array_keys($birthdaymonthyearmap))).')';
1564 }
1565 $sql .= ' ORDER BY birthday';
1566
1567 dol_syslog("agenda.lib.php::agenda_get_birthday_events", LOG_DEBUG);
1568 $resql = $db->query($sql);
1569 if (!$resql) {
1570 dol_print_error($db);
1571 return -1;
1572 }
1573
1574 $num = $db->num_rows($resql);
1575 $nbevents += $num;
1576
1577 $i = 0;
1578 while ($i < $num) {
1579 $obj = $db->fetch_object($resql);
1580
1581 $event = new ActionComm($db);
1582
1583 $event->id = $obj->rowid; // We put contact id in action id for birthdays events
1584 $event->ref = (string) $event->id;
1585
1586 $datebirth = dol_stringtotime($obj->birthday, 1);
1587 $datearray = dol_getdate($datebirth, true);
1588 // Use the year that matches the birthday month within the displayed period
1589 // (handles a week/month grid spanning two months or a year boundary)
1590 $birthdayyear = isset($birthdaymonthyearmap[(int) $datearray['mon']]) ? $birthdaymonthyearmap[(int) $datearray['mon']] : $year;
1591 $event->datep = dol_mktime(0, 0, 0, $datearray['mon'], $datearray['mday'], $birthdayyear, true); // For full day events, date are also GMT but they won't but converted during output
1592 $event->datef = $event->datep;
1593
1594 $event->type_code = 'BIRTHDAY';
1595 $event->type_label = '';
1596 $event->type_color = '';
1597 $event->type = 'birthdate';
1598 $event->type_picto = 'birthdate';
1599
1600 $event->label = $langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname, $obj->lastname);
1601 $event->percentage = 100;
1602 $event->fulldayevent = 1;
1603
1604 $event->contact_id = $obj->rowid;
1605
1606 $event->date_start_in_calendar = $event->datep;
1607 $event->date_end_in_calendar = $event->datef;
1608
1609 // Add an entry in eventarray for each day
1610 $daycursor = $event->datep;
1611 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1612 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1613 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1614
1615 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1616
1617 $eventarray[$daykey][] = $event;
1618
1619 $i++;
1620 }
1621
1622 return $num;
1623}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
show_array_actions_to_do($max=5)
Show actions to do array.
print_actions_filter( $form, $canedit, $status, $year, $month, $day, $showbirthday, $filtera, $filtert, $filtered, $pid, $socid, $action, $showextcals=array(), $actioncode='', $usergroupid=0, $excludetype='', $resourceid=0, $search_categ_cus=0, $search_import_key='')
Show filter form in agenda view.
show_array_last_actions_done($max=5)
Show last actions array.
calendars_prepare_head($param)
Define head array for tabs of agenda setup pages.
agenda_prepare_head()
Prepare array with list of tabs.
actions_prepare_head($object)
Prepare array with list of tabs.
agenda_build_eventarray($db, $hookmanager, $user, &$object, &$action, $mode, $year, $month, $day, $firstdaytoshow, $lastdaytoshow, $filters, $sincedatec=null)
Build $eventarray (list of ActionComm objects, indexed by day) for the agenda calendar views (month/w...
print $object position
Definition edit.php:206
Class to manage agenda events (actions)
Class to manage customers or prospects.
DAO Resource object.
Class to manage building of HTML components.
Class to help generate other html components Only common components are here.
Class to manage building of HTML components.
Class to manage forms for the module resource.
Class to manage third parties objects (customers, suppliers, prospects...)
$theme_datacolor
Definition index.php:1220
$cacheusers
Definition index.php:1218
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:65
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.