dolibarr 24.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
5 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
9 * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
12 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
34// Load Dolibarr environment
35require '../../main.inc.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
45require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
48require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
49require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
50require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
51require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
52require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
53require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
54require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
55require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
56require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
57require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
58
59// Load translation files required by the page
60$langs->loadLangs(["companies", "other", "commercial", "bills", "orders", "agenda", "mails"]);
61
62// Get Parameters
63$action = GETPOST('action', 'aZ09');
64$cancel = GETPOST('cancel', 'alpha');
65$backtopage = GETPOST('backtopage', 'alpha');
66$socpeopleassigned = GETPOST('socpeopleassigned', 'array');
67$origin = GETPOST('origin', 'alpha');
68$originid = GETPOSTINT('originid');
69$confirm = GETPOST('confirm', 'alpha');
70
71$fulldayevent = GETPOST('fullday', 'alpha');
72
73$aphour = GETPOSTINT('aphour');
74$apmin = GETPOSTINT('apmin');
75$p2hour = GETPOSTINT('p2hour');
76$p2min = GETPOSTINT('p2min');
77
78$addreminder = GETPOST('addreminder', 'alpha');
79$offsetvalue = GETPOSTINT('offsetvalue');
80$offsetunit = GETPOST('offsetunittype_duration', 'aZ09');
81$remindertype = GETPOST('selectremindertype', 'aZ09');
82$modelmail = GETPOSTINT('actioncommsendmodel_mail');
83$complete = GETPOST('complete', 'alpha'); // 'na' must be allowed
84$private = GETPOST('private', 'alphanohtml');
85if ($complete == 'na' || $complete == -2) {
86 $complete = -1;
87}
88
89$tzforfullday = null;
90if ($fulldayevent) {
91 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
92 // For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
93 $datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
94 $datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
95 //print $db->idate($datep); exit;
96} else {
97 $datep = dol_mktime($aphour, $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
98 $datef = dol_mktime($p2hour, $p2min, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
99}
100$reg = [];
101if (GETPOST('datep')) {
102 if (GETPOST('datep') == 'now') {
103 $datep = dol_now();
104 } elseif (preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])$/', GETPOST("datep"), $reg)) { // Try to not use this. Use instead '&datep=now'
105 $datep = dol_mktime(0, 0, 0, (int) $reg[2], (int) $reg[3], (int) $reg[1], 'tzuserrel');
106 }
107}
108
109$currentyear = (int) dol_print_date(dol_now(), '%Y');
110
111if (GETPOSTISSET("limityear") && GETPOSTINT("limityear") < 2100) {
112 $repeateventlimitdate = dol_mktime(23, 59, 59, GETPOSTISSET("limitmonth") ? GETPOSTINT("limitmonth") : 1, GETPOSTISSET("limitday") ? GETPOSTINT("limitday") : 1, GETPOSTINT("limityear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
113} else {
114 $repeateventlimitdate = dol_mktime(23, 59, 59, 12, 31, $currentyear, $tzforfullday ? $tzforfullday : 'tzuserrel');
115}
116
117// Security check
118$socid = GETPOSTINT('socid');
119if (empty($socid)) {
120 $socid = $user->socid; // External users: fall back to their own company (consistent with other card pages)
121}
122$id = GETPOSTINT('id');
123if ($user->socid && ($socid != $user->socid)) {
125}
126
127$error = GETPOST("error");
128$donotclearsession = GETPOST('donotclearsession') ? GETPOST('donotclearsession') : 0;
129// Per-event session keys to avoid cross-tab assignee bleed (see issue #30326).
130// When two tabs edit different events, both used to share the same flat
131// assignedtouser / assignedtoresource session buckets, so saving one event
132// could overwrite its assignees with the working set from the other tab.
133$sessionkeyassignedtouser = 'assignedtouser_'.($id > 0 ? $id : 'new');
134$sessionkeyassignedtoresource = 'assignedtoresource_'.($id > 0 ? $id : 'new');
135
136// Initialize Objects
137$object = new ActionComm($db);
138$cactioncomm = new CActionComm($db);
139$contact = new Contact($db);
140$formfile = new FormFile($db);
141
142$form = new Form($db);
143$formfile = new FormFile($db);
144$formactions = new FormActions($db);
145
146// Load object
147if ($id > 0 && $action != 'add') {
148 $ret = $object->fetch($id);
149 $ret1 = 0;
150 if ($ret > 0) {
151 $ret = $object->fetch_optionals();
152 $ret1 = $object->fetch_userassigned();
153 }
154 if ($ret < 0 || $ret1 < 0) {
155 dol_print_error(null, $object->error);
156 }
157}
158
159// fetch optionals attributes and labels
160$extrafields->fetch_name_optionals_label($object->table_element);
161
162if (empty($action) && empty($object->id)) {
163 $action = 'create';
164}
165
166// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
167$hookmanager->initHooks(['actioncard', 'globalcard']);
168
169$TRemindTypes = [];
170if (getDolGlobalString('AGENDA_REMINDER_BROWSER')) {
171 $TRemindTypes['browser'] = [
172 'label' => $langs->trans('BrowserPush'),
173 'disabled' => (getDolGlobalString('AGENDA_REMINDER_BROWSER') ? 0 : 1),
174 'type' => ActionCommReminder::TYPE_USER,
175 'data-html' => img_picto('', 'globe', 'class="pictofixedwidth"') . $langs->trans('BrowserPush'),
176 ];
177}
178if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
179 $TRemindTypes['email'] = [
180 'label' => $langs->trans('EMail'),
181 'disabled' => (getDolGlobalString('AGENDA_REMINDER_EMAIL') ? 0 : 1),
182 'type' => ActionCommReminder::TYPE_USER,
183 'data-html' => img_picto('', 'email', 'class="pictofixedwidth"') . $langs->trans('EMail'),
184 ];
185}
186if (getDolGlobalString('AGENDA_REMINDER_SMS')) {
187 $langs->load('sms');
188 $TRemindTypes['sms'] = [
189 'label' => $langs->trans('Sms'),
190 'disabled' => (getDolGlobalString('MAIN_SMS_SENDMODE') ? 0 : 1),
191 'type' => ActionCommReminder::TYPE_USER,
192 'data-html' => img_picto('', 'phoning_mobile', 'class="pictofixedwidth"') . $langs->trans('Sms'),
193 ];
194}
195$TDurationTypes = $form->getDurationTypes($langs);
196$TDurationTypesExcluded = ['y', 'm', 's'];
197$enablereminders = getDolGlobalString('AGENDA_REMINDER_EMAIL') || getDolGlobalString('AGENDA_REMINDER_BROWSER') || getDolGlobalString('AGENDA_REMINDER_SMS');
198$parameters = [
199 'socid' => $socid,
200 'TRemindTypes' => &$TRemindTypes,
201 'enablereminders' => &$enablereminders,
202 'TDurationTypes' => &$TDurationTypes,
203 'TDurationTypesExcluded' => &$TDurationTypesExcluded,
204];
205$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
206if ($reshook < 0) {
207 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
208}
209
210$result = restrictedArea($user, 'agenda', $object, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id');
211
212$usercancreate = $user->hasRight('agenda', 'allactions', 'create') || ((empty($object->id) || $object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'));
213$usercandelete = $user->hasRight('agenda', 'allactions', 'delete') || (($object->authorid === $user->id || $object->userownerid === $user->id) && $user->hasRight('agenda', 'myactions', 'delete'));
214
215
216/*
217 * Actions
218 */
219
220$listUserAssignedUpdated = false;
221$listResourceAssignedUpdated = false;
222$assignedtouser = [];
223
224// Remove user to assigned list
225if (empty($reshook) && (GETPOST('removedassigned') || GETPOST('removedassigned') == '0')) {
226 $idtoremove = GETPOST('removedassigned');
227
228 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
229 $tmpassigneduserids = json_decode($_SESSION[$sessionkeyassignedtouser], true);
230 } else {
231 $tmpassigneduserids = [];
232 }
233
234 foreach ($tmpassigneduserids as $key => $val) {
235 if ($val['id'] == $idtoremove || $val['id'] == -1) {
236 unset($tmpassigneduserids[$key]);
237 }
238 }
239
240 $_SESSION[$sessionkeyassignedtouser] = json_encode($tmpassigneduserids);
241 $donotclearsession = 1;
242 if ($action == 'add') { // Test on permission not required here
243 $action = 'create';
244 }
245 if ($action == 'update') { // Test on permission not required here
246 $action = 'edit';
247 }
248
249 $listUserAssignedUpdated = true;
250}
251// Remove resource to assigned list
252if (empty($reshook) && (GETPOST('removedassignedresource') || GETPOST('removedassignedresource') == '0')) {
253 $idtoremove = GETPOST('removedassignedresource');
254
255 if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
256 $tmpassignedresourceids = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
257 } else {
258 $tmpassignedresourceids = [];
259 }
260
261 foreach ($tmpassignedresourceids as $key => $val) {
262 if ($val['id'] == $idtoremove || $val['id'] == -1) {
263 unset($tmpassignedresourceids[$key]);
264 }
265 }
266
267 $_SESSION[$sessionkeyassignedtoresource] = json_encode($tmpassignedresourceids);
268
269 if ($action == 'add' && $usercancreate) {
270 $action = 'create';
271 }
272 if ($action == 'update' && $usercancreate) {
273 $action = 'edit';
274 }
275
276 $listResourceAssignedUpdated = true;
277}
278
279// Add user to assigned list
280if (empty($reshook) && (GETPOST('addassignedtouser') || GETPOST('updateassignedtouser'))) {
281 // Add a new user
282 if (GETPOST('assignedtouser') > 0) {
283 $assignedtouser = [];
284 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
285 $assignedtouser = json_decode($_SESSION[$sessionkeyassignedtouser], true);
286 }
287 $assignedtouser[GETPOST('assignedtouser')] = array('id' => GETPOSTINT('assignedtouser'), 'transparency' => GETPOST('transparency'), 'mandatory' => 1);
288 $_SESSION[$sessionkeyassignedtouser] = json_encode($assignedtouser);
289 }
290 $donotclearsession = 1;
291 if ($action == 'add' && $usercancreate) {
292 $action = 'create';
293 }
294 if ($action == 'update' && $usercancreate) {
295 $action = 'edit';
296 }
297
298 $listUserAssignedUpdated = true;
299}
300
301// Add resource to assigned list
302if (empty($reshook) && (GETPOST('addassignedtoresource') || GETPOST('updateassignedtoresource'))) {
303 // Add a new user
304 if (GETPOST('assignedtoresource') > 0) {
305 $assignedtoresource = [];
306 if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
307 $assignedtoresource = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
308 }
309 $assignedtoresource[GETPOST('assignedtoresource')] = array('id' => GETPOSTINT('assignedtoresource'), 'transparency' => GETPOST('transparency'), 'mandatory' => 1);
310 $_SESSION[$sessionkeyassignedtoresource] = json_encode($assignedtoresource);
311 }
312 $donotclearsession = 1;
313 if ($action == 'add' && $usercancreate) {
314 $action = 'create';
315 }
316 if ($action == 'update' && $usercancreate) {
317 $action = 'edit';
318 }
319
320 $listResourceAssignedUpdated = true;
321}
322
323// Link to a project
324if (empty($reshook) && $action == 'classin' && ($user->hasRight('agenda', 'allactions', 'create') ||
325 (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create')))) {
326 //$object->fetch($id);
327 $object->setProject(GETPOSTINT('projectid'));
328}
329
330// Action clone object
331if (empty($reshook) && $action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
332 // @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp
333 if (1 == 0 && !GETPOST('clone_content') && !GETPOST('clone_receivers')) {
334 setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
335 } else {
336 if ($id > 0) {
337 //$object->fetch($id);
338 if (!empty($object->socpeopleassigned)) {
339 reset($object->socpeopleassigned);
340 $object->contact_id = (int) key($object->socpeopleassigned);
341 }
342 $result = $object->createFromClone($user, GETPOSTINT('socid'));
343 if ($result > 0) {
344 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
345 exit();
346 } else {
347 setEventMessages($object->error, $object->errors, 'errors');
348 $action = '';
349 }
350 }
351 }
352}
353
354// Add event
355if (empty($reshook) && $action == 'add' && $usercancreate) {
356 $error = 0;
357
358 if (empty($backtopage)) {
359 if ($socid > 0) {
360 $backtopage = DOL_URL_ROOT.'/societe/agenda.php?socid='.$socid;
361 } else {
362 $backtopage = DOL_URL_ROOT.'/comm/action/index.php';
363 }
364 }
365
366 if (!empty($socpeopleassigned[0])) {
367 $result = $contact->fetch($socpeopleassigned[0]);
368 }
369
370 if ($cancel) {
371 header("Location: ".$backtopage);
372 exit;
373 }
374
375 $percentage = in_array(GETPOST('status'), array(-1, 100)) ? GETPOST('status') : (in_array($complete, array(-1, 100)) ? $complete : GETPOSTINT("percentage")); // If status is -1 or 100, percentage is not defined and we must use status
376
377 // Clean parameters
378 if ($fulldayevent) {
379 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
380 // For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
381 $datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
382 $datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
383 } else {
384 $datep = dol_mktime(GETPOSTINT("aphour"), GETPOSTINT("apmin"), GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
385 $datef = dol_mktime(GETPOSTINT("p2hour"), GETPOSTINT("p2min"), GETPOSTINT("apsec"), GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
386 }
387 //set end date to now if percentage is set to 100 and end date not set
388 $datef = (!$datef && $percentage == 100) ? dol_now() : $datef;
389
390 // Check parameters
391 if (!$datef && $percentage == 100) {
392 $error++;
393 $donotclearsession = 1;
394 $action = 'create';
395 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
396 }
397
398 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE') && !GETPOST('label')) {
399 $error++;
400 $donotclearsession = 1;
401 $action = 'create';
402 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Title")), null, 'errors');
403 }
404
405 // Initialisation object cactioncomm
406 if (GETPOSTISSET('actioncode') && !GETPOST('actioncode', 'aZ09')) { // actioncode is '0'
407 $error++;
408 $donotclearsession = 1;
409 $action = 'create';
410 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
411 } else {
412 $object->type_code = GETPOST('actioncode', 'aZ09');
413 }
414
415 $listofresourceid = [];
416
417 if (!$error) {
418 // Initialisation of object actioncomm
419 $object->priority = GETPOSTISSET("priority") ? GETPOSTINT("priority") : 0;
420 $object->fulldayevent = ($fulldayevent ? 1 : 0);
421 $object->location = GETPOST("location", 'alphanohtml');
422 $object->label = GETPOST('label', 'alphanohtml');
423
424 if (GETPOST("elementtype", 'alpha')) {
425 $elProp = getElementProperties(GETPOST("elementtype", 'alpha'));
426 $modulecodetouseforpermissioncheck = $elProp['module'];
427 // Keep permission check aligned with rights class aliases (see restrictedArea()).
428 $submodulecodetouseforpermissioncheck = $elProp['subelement'];
429
430 switch ($modulecodetouseforpermissioncheck) {
431 case 'productbatch':
432 $modulecodetouseforpermissioncheck = 'produit';
433 break;
434 case 'eventorganization':
435 // Event organization relies on Project permissions
436 $modulecodetouseforpermissioncheck = 'projet';
437 $submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
438 break;
439 default:
440 // No mapping needed, keep original values
441 break;
442 }
443
444 $hasPermissionOnLinkedObject = 0;
445 if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
446 $hasPermissionOnLinkedObject = 1;
447 } elseif ($user->hasRight($modulecodetouseforpermissioncheck, $submodulecodetouseforpermissioncheck, 'read')) {
448 $hasPermissionOnLinkedObject = 1;
449 }
450
451 if ($hasPermissionOnLinkedObject) {
452 $object->fk_element = GETPOSTINT("fk_element");
453 $object->elementid = GETPOSTINT("fk_element");
454 $object->elementtype = GETPOST("elementtype", 'alpha');
455 }
456 }
457
458 if (!GETPOST('label')) {
459 if (GETPOST('actioncode', 'aZ09') == 'AC_RDV' && $contact->getFullName($langs)) {
460 $object->label = $langs->transnoentitiesnoconv("TaskRDVWith", $contact->getFullName($langs));
461 } else {
462 if ($langs->trans("Action".$object->type_code) != "Action".$object->type_code) {
463 $object->label = $langs->transnoentitiesnoconv("Action".$object->type_code)."\n";
464 } else {
465 $cactioncomm->fetch($object->type_code);
466 $object->label = $cactioncomm->label;
467 }
468 }
469 }
470 $object->fk_project = GETPOSTISSET("projectid") ? GETPOSTINT("projectid") : 0;
471
472 $taskid = GETPOSTINT('taskid');
473 if (!empty($taskid)) {
474 $taskProject = new Task($db);
475 if ($taskProject->fetch($taskid) > 0) {
476 $object->fk_project = $taskProject->fk_project;
477 }
478
479 $object->fk_element = $taskid;
480 $object->elementid = $taskid;
481 $object->elementtype = 'project_task';
482 }
483
484 $object->datep = $datep;
485 $object->datef = $datef;
486 $object->percentage = $percentage;
487 $object->duree = (((int) GETPOST('dureehour') * 60) + (int) GETPOST('dureemin')) * 60;
488
489 $transparency = (GETPOST("transparency") == 'on' ? 1 : 0);
490
491 $listofuserid = [];
492 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
493 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
494 }
495
496 if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
497 $listofresourceid = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
498 }
499
500 $i = 0;
501 foreach ($listofuserid as $key => $value) {
502 if ($i == 0) { // First entry
503 if ($value['id'] > 0) {
504 $object->userownerid = $value['id'];
505 }
506 $object->transparency = $transparency;
507 }
508
509 $object->userassigned[$value['id']] = array('id' => $value['id'], 'transparency' => $transparency);
510
511 $i++;
512 }
513 }
514
515 $object->note_private = trim(GETPOST("note", "restricthtml"));
516
517 if (GETPOSTISSET("contactid")) {
518 $object->contact_id = GETPOSTINT("contactid");
519 $object->fetch_contact();
520 }
521
522 if (GETPOSTINT('socid') > 0) {
523 $object->socid = GETPOSTINT('socid');
524 $object->fetch_thirdparty();
525 }
526
527 // Check parameters
528 if (empty($object->userownerid) && empty($_SESSION[$sessionkeyassignedtouser])) {
529 $error++;
530 $donotclearsession = 1;
531 $action = 'create';
532 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ActionsOwnedBy")), null, 'errors');
533 }
534 if ($object->type_code == 'AC_RDV' && ($datep == '' || ($datef == '' && empty($fulldayevent)))) {
535 $error++;
536 $donotclearsession = 1;
537 $action = 'create';
538 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
539 }
540
541 if (!GETPOST('apyear') && !GETPOST('adyear')) {
542 $error++;
543 $donotclearsession = 1;
544 $action = 'create';
545 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
546 }
547
548 foreach ($socpeopleassigned as $cid) {
549 $object->socpeopleassigned[$cid] = array('id' => $cid);
550 }
551 if (!empty($object->socpeopleassigned)) {
552 reset($object->socpeopleassigned);
553 $object->contact_id = key($object->socpeopleassigned);
554 }
555
556 // Fill array 'array_options' with data from add form
557 $ret = $extrafields->setOptionalsFromPost(null, $object);
558 if ($ret < 0) {
559 $error++;
560 $donotclearsession = 1;
561 $action = 'create';
562 }
563
564
565 if (!$error) {
566 $db->begin();
567
568 $dayinyear = dol_print_date($object->datep, '%m%d');
569 $dayinmonth = dol_print_date($object->datep, '%d');
570 $dayinweek = dol_print_date($object->datep, '%w');
571
572 $selectedrecurrulefreq = 'no';
573 $selectedrecurrulebyyearmonthday = '';
574 $selectedrecurrulebymonthday = '';
575 $selectedrecurrulebyday = '';
576 $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
577 $object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'YEARLY') ? "_BYYEARMONTHDAY".((int) $dayinyear) : "";
578 $object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'MONTHLY') ? "_BYMONTHDAY".((int) $dayinmonth) : "";
579 $object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'WEEKLY') ? "_BYDAY".((int) $dayinweek) : "";
580
581 $reg1 = [];
582 $reg2 = [];
583 $reg3 = [];
584 $reg4 = [];
585 if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) {
586 $selectedrecurrulefreq = $reg1[1];
587 }
588 if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg4)) {
589 $selectedrecurrulebyyearmonthday = (int) $reg4[1];
590 }
591 if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) {
592 $selectedrecurrulebymonthday = (int) $reg2[1];
593 }
594 if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg3)) {
595 $selectedrecurrulebyday = (int) $reg3[1];
596 }
597
598 // Is event recurrent ?
599 $eventisrecurring = 0;
600 $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
601 if ($userepeatevent && !empty($selectedrecurrulefreq) && $selectedrecurrulefreq != 'no') {
602 $eventisrecurring = 1;
603 $object->recurid = dol_print_date(dol_now('gmt'), 'dayhourlog', 'gmt');
604 $object->recurdateend = dol_mktime(0, 0, 0, GETPOSTINT('limitmonth'), GETPOSTINT('limitday'), GETPOSTINT('limityear'));
605 } else {
606 unset($object->recurid);
607 unset($object->recurrule);
608 unset($object->recurdateend);
609 }
610
611 // Creation of action/event
612 $idaction = $object->create($user);
613 $moreparam = '';
614
615 if ($idaction > 0) {
616 if (!$object->error) {
617 if (is_array($listofresourceid) && count($listofresourceid)) {
618 foreach ($listofresourceid as $resource_id => $val) {
619 $resource_type = 'dolresource';
620 $busy = 1;//GETPOSTINT('busy');
621
622 // Resources association
623 if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK')) {
624 $eventDateStart = $object->datep;
625 $eventDateEnd = $object->datef;
626 $isFullDayEvent = $object->fulldayevent;
627 if (empty($eventDateEnd)) {
628 if ($isFullDayEvent) {
629 $eventDateStartArr = dol_getdate($eventDateStart);
630 $eventDateStart = dol_mktime(0, 0, 0, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
631 $eventDateEnd = dol_mktime(23, 59, 59, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
632 }
633 }
634
635 $sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
636 $sql .= " FROM " . MAIN_DB_PREFIX . "element_resources as er";
637 $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "resource as r ON r.rowid = er.resource_id AND er.resource_type = '" . $db->escape($resource_type) . "'";
638 $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "actioncomm as ac ON ac.id = er.element_id AND er.element_type = '" . $db->escape($object->element) . "'";
639 $sql .= " WHERE er.resource_id = " . ((int) $resource_id);
640 $sql .= " AND er.busy = 1";
641 $sql .= " AND (";
642
643 // event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
644 $sql .= " (ac.datep <= '" . $db->idate($eventDateStart) . "' AND (ac.datep2 IS NULL OR ac.datep2 >= '" . $db->idate($eventDateStart) . "'))";
645 // event date end between ac.datep and ac.datep2
646 if (!empty($eventDateEnd)) {
647 $sql .= " OR (ac.datep <= '" . $db->idate($eventDateEnd) . "' AND (ac.datep2 >= '" . $db->idate($eventDateEnd) . "'))";
648 }
649 // event date start before ac.datep and event date end after ac.datep2
650 $sql .= " OR (";
651 $sql .= "ac.datep >= '" . $db->idate($eventDateStart) . "'";
652 if (!empty($eventDateEnd)) {
653 $sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '" . $db->idate($eventDateEnd) . "')";
654 }
655 $sql .= ")";
656
657 $sql .= ")";
658 $resql = $db->query($sql);
659 if (!$resql) {
660 $error++;
661 $object->error = $db->lasterror();
662 $object->errors[] = $object->error;
663 } else {
664 if ($db->num_rows($resql) > 0) {
665 // Resource already in use
666 $error++;
667 $object->error = $langs->trans('ErrorResourcesAlreadyInUse') . ' : ';
668 while ($obj = $db->fetch_object($resql)) {
669 $object->error .= '<br> - ' . $langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label . ' [' . $obj->ac_id . ']');
670 }
671 $object->errors[] = $object->error;
672
673 setEventMessages($object->error, null, 'errors');
674 }
675 $db->free($resql);
676 }
677 }
678
679 if (!$error) {
680 $res = $object->add_element_resource($resource_id, $resource_type, $busy, $val['mandatory']);
681 }
682 }
683 }
684
685 unset($_SESSION[$sessionkeyassignedtoresource]);
686
687
688 // Category association
689 if (!$error) {
690 $categories = GETPOST('categories', 'array');
691 $object->setCategories($categories);
692 }
693
694 unset($_SESSION[$sessionkeyassignedtouser]);
695
696 if ($user->id != $object->userownerid) {
697 $moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
698 }
699
700 // Create reminders
701 if (!$error && $addreminder == 'on') {
702 $actionCommReminder = new ActionCommReminder($db);
703
704 $dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
705
706 $actionCommReminder->dateremind = $dateremind;
707 $actionCommReminder->typeremind = $remindertype;
708 $actionCommReminder->offsetunit = $offsetunit;
709 $actionCommReminder->offsetvalue = $offsetvalue;
710 $actionCommReminder->status = $actionCommReminder::STATUS_TODO;
711 $actionCommReminder->fk_actioncomm = $object->id;
712 if ($remindertype == 'email') {
713 $actionCommReminder->fk_email_template = $modelmail;
714 }
715
716 // the notification must be created for every user assigned to the event
717 foreach ($object->userassigned as $userassigned) {
718 $actionCommReminder->fk_user = $userassigned['id'];
719 $res = $actionCommReminder->create($user);
720
721 if ($res <= 0) {
722 // If error
723 $langs->load("errors");
724 $error++;
725 setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
726 $action = 'create';
727 $donotclearsession = 1;
728 break;
729 }
730 }
731 }
732
733 // Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page.
734 /*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0';
735 $moreparam .= ($moreparam ? '&' : '').'search_status=-1';
736 $moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
737 */
738 $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
739
740 // if (!empty($backtopage)) {
741 // dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
742 // header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
743 // } elseif ($idaction) {
744 // header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
745 // } else {
746 // header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
747 // }
748 // exit;
749 } else {
750 // If error
751 $langs->load("errors");
752 $error++;
753 setEventMessages($langs->trans($object->error), null, 'errors');
754 $action = 'create';
755 $donotclearsession = 1;
756 }
757 } else {
758 $error++;
759 setEventMessages($object->error, $object->errors, 'errors');
760 $action = 'create';
761 $donotclearsession = 1;
762 }
763
764 // Manage other events in case of recurring event
765 if (!$error && $eventisrecurring) {
766 $dayoffset = 0;
767 $monthoffset = 0;
768 $yearoffset = 0;
769 // We set first date of recurrence and offsets
770 if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
771 $firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear"));
772 $datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstdatearray['month'], $firstdatearray['first_day'], $firstdatearray['year'], $tzforfullday ? $tzforfullday : 'tzuserrel');
773 $datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after
774 $dayoffset = 7;
775 $monthoffset = 0;
776 $yearoffset = 0;
777 } elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) {
778 $firstday = $selectedrecurrulebymonthday;
779 $firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the month after
780 $datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstmonth, $firstday, GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
781 $datep = dol_time_plus_duree($datep, 1, 'm');//We begin the month after
782 $dayoffset = 0;
783 $monthoffset = 1;
784 $yearoffset = 0;
785 } elseif ($selectedrecurrulefreq == 'YEARLY' && !empty($selectedrecurrulebyyearmonthday)) {
786 $datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
787 $datep = dol_time_plus_duree($datep, 1, 'y');//We begin the year after
788 $dayoffset = 0;
789 $monthoffset = 0;
790 $yearoffset = 1;
791 } else {
792 $error++;
793 }
794 // End date
795 // Set date of end of event
796 $deltatime = num_between_day($object->datep, $datep);
797 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
798 $datef = dol_time_plus_duree($datef, $deltatime, 'd');
799
800 while ($datep <= $repeateventlimitdate && !$error) {
801 $finalobject = clone $object;
802
803
804 $finalobject->datep = $datep;
805 $finalobject->datef = $datef;
806 // Creation of action/event
807 $idaction = $finalobject->create($user);
808
809 if ($idaction > 0) {
810 if (!$finalobject->error) {
811 // Category association
812 $categories = GETPOST('categories', 'array');
813 $finalobject->setCategories($categories);
814
815 unset($_SESSION[$sessionkeyassignedtouser]);
816
817 $moreparam = '';
818 if ($user->id != $finalobject->userownerid) {
819 $moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
820 }
821
822 // Create reminders
823 if ($addreminder == 'on') {
824 $actionCommReminder = new ActionCommReminder($db);
825
826 $dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
827
828 $actionCommReminder->dateremind = $dateremind;
829 $actionCommReminder->typeremind = $remindertype;
830 $actionCommReminder->offsetunit = $offsetunit;
831 $actionCommReminder->offsetvalue = $offsetvalue;
832 $actionCommReminder->status = $actionCommReminder::STATUS_TODO;
833 $actionCommReminder->fk_actioncomm = $finalobject->id;
834 if ($remindertype == 'email') {
835 $actionCommReminder->fk_email_template = $modelmail;
836 }
837
838 // the notification must be created for every user assigned to the event
839 foreach ($finalobject->userassigned as $userassigned) {
840 $actionCommReminder->fk_user = $userassigned['id'];
841 $res = $actionCommReminder->create($user);
842
843 if ($res <= 0) {
844 // If error
845 $error++;
846 $langs->load("errors");
847 setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
848 $action = 'create';
849 $donotclearsession = 1;
850 break;
851 }
852 }
853 }
854
855 // Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page.
856 /*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0';
857 $moreparam .= ($moreparam ? '&' : '').'search_status=-1';
858 $moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
859 */
860 $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
861 } else {
862 // If error
863 $error++;
864 $langs->load("errors");
865 $error = $langs->trans($finalobject->error);
866 setEventMessages($error, null, 'errors');
867 $action = 'create';
868 $donotclearsession = 1;
869 }
870 } else {
871 $error++;
872 setEventMessages($finalobject->error, $finalobject->errors, 'errors');
873 $action = 'create';
874 $donotclearsession = 1;
875 }
876
877 // If event is not recurrent, we stop here
878 if (!($userepeatevent && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday"))) {
879 break;
880 }
881
882 // increment date for recurrent events
883 $datep = dol_time_plus_duree($datep, $dayoffset, 'd');
884 $datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
885 $datep = dol_time_plus_duree($datep, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
886 $datef = dol_time_plus_duree($datef, $dayoffset, 'd');
887 $datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
888 $datef = dol_time_plus_duree($datef, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
889 }
890 }
891
892 if ($error) {
893 $db->rollback();
894 } else {
895 $db->commit();
896 }
897
898 if (!empty($backtopage) && !$error) {
899 dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
900 header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
901 } elseif ($idaction) {
902 header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
903 } else {
904 header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
905 }
906 exit;
907 }
908}
909
910// Action update event
911if (empty($reshook) && $action == 'update' && $usercancreate) {
912 if (empty($cancel)) {
913 $fulldayevent = GETPOST('fullday');
914 $aphour = GETPOSTINT('aphour');
915 $apmin = GETPOSTINT('apmin');
916 $p2hour = GETPOSTINT('p2hour');
917 $p2min = GETPOSTINT('p2min');
918 $percentage = in_array(GETPOST('status'), array(-1, 100)) ? GETPOST('status') : (in_array($complete, array(-1, 100)) ? $complete : GETPOSTINT("percentage")); // If status is -1 or 100, percentage is not defined and we must use status
919
920 // Clean parameters
921 if ($aphour == -1) {
922 $aphour = '0';
923 }
924 if ($apmin == -1) {
925 $apmin = '0';
926 }
927 if ($p2hour == -1) {
928 $p2hour = '0';
929 }
930 if ($p2min == -1) {
931 $p2min = '0';
932 }
933
934 $object->fetch($id);
935 $object->fetch_optionals();
936 $object->fetch_userassigned();
937 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
938
939 // Clean parameters
940 if ($fulldayevent) {
941 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
942 // For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
943 $datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
944 $datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
945 } else {
946 if (!GETPOSTISSET('ap') && !GETPOSTISSET('aphour') && !GETPOSTISSET('apmin')) { // If date fields are disabled, we keep old value
947 $datep = $object->datep;
948 } else {
949 $datep = dol_mktime(GETPOSTINT("aphour"), GETPOSTINT("apmin"), GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
950 }
951 if (!GETPOSTISSET('p2') && !GETPOSTISSET('p2hour') && !GETPOSTISSET('p2min')) { // If date fields are disabled, we keep old value
952 $datef = $object->datef;
953 } else {
954 $datef = dol_mktime(GETPOSTINT("p2hour"), GETPOSTINT("p2min"), GETPOSTINT("apsec"), GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
955 }
956 }
957
958 //set end date to now if percentage is set to 100 and end date not set
959 $datef = (!$datef && $percentage == 100) ? dol_now() : $datef;
960
961 if ($object->elementtype == 'ticket') { // code should be TICKET_MSG, TICKET_MSG_PRIVATE, TICKET_MSG_SENTBYMAIL, TICKET_MSG_PRIVATE_SENTBYMAIL
962 if ($private) {
963 if ($object->code == 'TICKET_MSG') {
964 $object->code = 'TICKET_MSG_PRIVATE';
965 }
966 if ($object->code == 'TICKET_MSG_SENTBYMAIL') {
967 $object->code = 'TICKET_MSG_PRIVATE_SENTBYMAIL';
968 }
969 } else {
970 if ($object->code == 'TICKET_MSG_PRIVATE') {
971 $object->code = 'TICKET_MSG';
972 }
973 if ($object->code == 'TICKET_MSG_PRIVATE_SENTBYMAIL') {
974 $object->code = 'TICKET_MSG_SENTBYMAIL';
975 }
976 }
977 // type_id and type_code is not modified
978 } else {
979 $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm');
980 $object->type_code = GETPOST("actioncode", 'aZ09');
981 }
982
983 $object->label = GETPOST("label", "alphanohtml");
984 $object->datep = $datep;
985 $object->datef = $datef;
986 $object->percentage = $percentage;
987 $object->priority = GETPOSTINT("priority");
988 $object->fulldayevent = GETPOST("fullday") ? 1 : 0;
989 $object->location = GETPOST('location', "alphanohtml");
990 $object->socid = GETPOSTINT("socid");
991 $socpeopleassigned = GETPOST("socpeopleassigned", 'array');
992 $object->socpeopleassigned = [];
993 foreach ($socpeopleassigned as $cid) {
994 $object->socpeopleassigned[$cid] = array('id' => $cid);
995 }
996 $object->contact_id = GETPOSTINT("contactid");
997 if (empty($object->contact_id) && !empty($object->socpeopleassigned)) {
998 reset($object->socpeopleassigned);
999 $object->contact_id = (int) key($object->socpeopleassigned);
1000 }
1001 $object->fk_project = GETPOSTINT("projectid");
1002 $taskid = GETPOSTINT('taskid');
1003 if (!empty($taskid)) {
1004 $taskProject = new Task($db);
1005 if ($taskProject->fetch($taskid) > 0) {
1006 $object->fk_project = $taskProject->fk_project;
1007 }
1008
1009 $object->fk_element = $taskid;
1010 $object->elementid = $taskid;
1011 $object->elementtype = 'project_task';
1012 }
1013
1014 $object->note_private = trim(GETPOST("note", "restricthtml"));
1015
1016 if (GETPOST("elementtype", 'alpha')) {
1017 $elProp = getElementProperties(GETPOST("elementtype", 'alpha'));
1018 $modulecodetouseforpermissioncheck = $elProp['module'];
1019 // Keep permission check aligned with rights class aliases (see restrictedArea()).
1020 $submodulecodetouseforpermissioncheck = $elProp['subelement'];
1021
1022 switch ($modulecodetouseforpermissioncheck) {
1023 case 'productbatch':
1024 $modulecodetouseforpermissioncheck = 'produit';
1025 break;
1026 case 'eventorganization':
1027 // Event organization relies on Project permissions
1028 $modulecodetouseforpermissioncheck = 'projet';
1029 $submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
1030 break;
1031 default:
1032 // No mapping needed, keep original values
1033 break;
1034 }
1035
1036 $hasPermissionOnLinkedObject = 0;
1037 if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
1038 $hasPermissionOnLinkedObject = 1;
1039 }
1040 if ($hasPermissionOnLinkedObject) {
1041 $object->fk_element = GETPOSTINT("fk_element");
1042 $object->elementid = GETPOSTINT("fk_element");
1043 $object->elementtype = GETPOST("elementtype", 'alpha');
1044 }
1045 }
1046
1047
1048 $transparency = (GETPOST("transparency") == 'on' ? 1 : 0);
1049
1050 // Users
1051 $listofuserid = [];
1052 if (!empty($_SESSION[$sessionkeyassignedtouser])) { // Now concat assigned users
1053 // Restore array with key with same value than param 'id'
1054 $tmplist1 = json_decode($_SESSION[$sessionkeyassignedtouser], true);
1055 foreach ($tmplist1 as $key => $val) {
1056 if ($val['id'] > 0 && $val['id'] != $assignedtouser) {
1057 $listofuserid[$val['id']] = $val;
1058 }
1059 }
1060 } else {
1061 $assignedtouser = (!empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : 0);
1062 if ($assignedtouser) {
1063 $listofuserid[$assignedtouser] = array('id' => $assignedtouser, 'mandatory' => 0, 'transparency' => ($user->id == $assignedtouser ? $transparency : '')); // Owner first
1064 }
1065 }
1066 $object->userassigned = [];
1067 $object->userownerid = 0; // Clear old content
1068 $i = 0;
1069 foreach ($listofuserid as $key => $val) {
1070 if ($i == 0) {
1071 $object->userownerid = $val['id'];
1072 }
1073 $object->userassigned[$val['id']] = array('id' => $val['id'], 'mandatory' => 0, 'transparency' => ($user->id == $val['id'] ? $transparency : ''));
1074 $i++;
1075 }
1076
1077 $object->transparency = $transparency; // We set transparency on event (even if we can also store it on each user, standard says this property is for event)
1078 // TODO store also transparency on owner user
1079
1080 // Check parameters
1081 if (GETPOSTISSET('actioncode') && !GETPOST('actioncode', 'aZ09')) { // actioncode is '0'
1082 $error++;
1083 $donotclearsession = 1;
1084 $action = 'edit';
1085 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1086 } else {
1087 $result = $cactioncomm->fetch(GETPOST('actioncode', 'aZ09'));
1088 }
1089 if (empty($object->userownerid)) {
1090 $error++;
1091 $donotclearsession = 1;
1092 $action = 'edit';
1093 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ActionsOwnedBy")), null, 'errors');
1094 }
1095
1096 // Fill array 'array_options' with data from add form
1097 $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
1098 if ($ret < 0) {
1099 $error++;
1100 }
1101
1102 if (!$error) {
1103 // check if an event resource is already in use
1104 if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
1105 $eventDateStart = $object->datep;
1106 $eventDateEnd = $object->datef;
1107
1108 $sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
1109 $sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
1110 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
1111 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
1112 $sql .= " WHERE ac.id <> ".((int) $object->id);
1113 $sql .= " AND er.resource_id IN (";
1114 $sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
1115 $sql .= " WHERE element_id = ".((int) $object->id);
1116 $sql .= " AND element_type = '".$db->escape($object->element)."'";
1117 $sql .= " AND busy = 1";
1118 $sql .= ")";
1119 $sql .= " AND er.busy = 1";
1120 $sql .= " AND (";
1121
1122 // event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
1123 $sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
1124 // event date end between ac.datep and ac.datep2
1125 if (!empty($eventDateEnd)) {
1126 $sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
1127 }
1128 // event date start before ac.datep and event date end after ac.datep2
1129 $sql .= " OR (";
1130 $sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
1131 if (!empty($eventDateEnd)) {
1132 $sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
1133 }
1134 $sql .= ")";
1135
1136 $sql .= ")";
1137 $resql = $db->query($sql);
1138 if (!$resql) {
1139 $error++;
1140 $object->error = $db->lasterror();
1141 $object->errors[] = $object->error;
1142 } else {
1143 if ($db->num_rows($resql) > 0) {
1144 // Resource already in use
1145 $error++;
1146 $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
1147 while ($obj = $db->fetch_object($resql)) {
1148 $object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
1149 }
1150 $object->errors[] = $object->error;
1151 }
1152 $db->free($resql);
1153 }
1154
1155 if ($error) {
1156 setEventMessages($object->error, $object->errors, 'errors');
1157 }
1158 }
1159 }
1160
1161 if (!$error) {
1162 $db->begin();
1163
1164 $result = $object->update($user);
1165
1166 if ($result > 0) {
1167 // Category association
1168 $categories = GETPOST('categories', 'array');
1169 $object->setCategories($categories);
1170
1171 $object->loadReminders($remindertype, 0, false);
1172
1173 // If there is reminders, we remove them
1174 if (!empty($object->reminders)) {
1175 foreach ($object->reminders as $reminder) {
1176 if ($reminder->status < 1) { // If already sent, we never remove it
1177 $reminder->delete($user);
1178 }
1179 }
1180 $object->reminders = [];
1181 }
1182
1183 // Create reminders for every assigned user if reminder is on
1184 if ($addreminder == 'on') {
1185 $actionCommReminder = new ActionCommReminder($db);
1186
1187 $dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
1188
1189 $actionCommReminder->dateremind = $dateremind;
1190 $actionCommReminder->typeremind = $remindertype;
1191 $actionCommReminder->offsetunit = $offsetunit;
1192 $actionCommReminder->offsetvalue = $offsetvalue;
1193 $actionCommReminder->status = $actionCommReminder::STATUS_TODO;
1194 $actionCommReminder->fk_actioncomm = $object->id;
1195 if ($remindertype == 'email') {
1196 $actionCommReminder->fk_email_template = $modelmail;
1197 }
1198
1199 // the notification must be created for every user assigned to the event
1200 foreach ($object->userassigned as $userassigned) {
1201 $actionCommReminder->fk_user = $userassigned['id'];
1202
1203 // We update the event, so we recreate the notification event.
1204 // First we delete all reminders for the user and the type of reminding (all offset dates).
1205 $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
1206 $sqldelete .= " WHERE fk_user = ".((int) $actionCommReminder->fk_user)." AND fk_actioncomm = ".((int) $object->id)." AND typeremind = '".$db->escape($remindertype)."'";
1207 $resqldelete = $db->query($sqldelete);
1208
1209 $res = $actionCommReminder->create($user);
1210
1211 if ($res <= 0) {
1212 // If error
1213 $langs->load("errors");
1214 $error = $langs->trans('ErrorReminderActionCommCreation');
1215 setEventMessages($error, null, 'errors');
1216 $action = 'create';
1217 $donotclearsession = 1;
1218 break;
1219 }
1220 }
1221 }
1222
1223 if (!$error) {
1224 unset($_SESSION[$sessionkeyassignedtouser]);
1225 unset($_SESSION[$sessionkeyassignedtoresource]);
1226
1227 $db->commit();
1228 } else {
1229 $db->rollback();
1230 $action = 'edit';
1231 }
1232 } else {
1233 setEventMessages($object->error, $object->errors, 'errors');
1234 $db->rollback();
1235 }
1236 }
1237 }
1238
1239 if (!$error) {
1240 if (!empty($backtopage)) {
1241 unset($_SESSION[$sessionkeyassignedtouser]);
1242 header("Location: ".$backtopage);
1243 exit;
1244 }
1245 }
1246}
1247
1248// Delete event
1249if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes' && $usercandelete) {
1250 $object->fetch($id);
1251 $object->fetch_optionals();
1252 $object->fetch_userassigned();
1253 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1254
1255 $result = $object->delete($user);
1256
1257 if ($result >= 0) {
1258 header("Location: index.php");
1259 exit;
1260 } else {
1261 setEventMessages($object->error, $object->errors, 'errors');
1262 }
1263}
1264
1265/*
1266 * Action move update, used when user move an event in calendar by drag'n drop
1267 * TODO Move this into page comm/action/index that trigger this call by the drag and drop of event.
1268 */
1269if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate' && $usercancreate) {
1270 $error = 0;
1271
1272 $shour = (int) dol_print_date($object->datep, "%H", 'tzuserrel'); // We take the date visible by user $newdate is also date visible by user.
1273 $smin = (int) dol_print_date($object->datep, "%M", 'tzuserrel');
1274
1275 $newdate = GETPOST('newdate', 'alpha');
1276 if (empty($newdate) || strpos($newdate, 'dayevent_') != 0) {
1277 header("Location: ".$backtopage, true, 307);
1278 exit;
1279 }
1280
1281 $datep = dol_mktime($shour, $smin, 0, (int) substr($newdate, 13, 2), (int) substr($newdate, 15, 2), (int) substr($newdate, 9, 4), 'tzuserrel');
1282 //print dol_print_date($datep, 'dayhour');exit;
1283
1284 if ($datep != $object->datep) {
1285 if (!empty($object->datef)) {
1286 $object->datef += (int) $datep - $object->datep;
1287 }
1288 $object->datep = $datep;
1289
1290 if (!$error) {
1291 // check if an event resource is already in use
1292 if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
1293 $eventDateStart = $object->datep;
1294 $eventDateEnd = $object->datef;
1295
1296 $sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
1297 $sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
1298 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
1299 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
1300 $sql .= " WHERE ac.id <> ".((int) $object->id);
1301 $sql .= " AND er.resource_id IN (";
1302 $sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
1303 $sql .= " WHERE element_id = ".((int) $object->id);
1304 $sql .= " AND element_type = '".$db->escape($object->element)."'";
1305 $sql .= " AND busy = 1";
1306 $sql .= ")";
1307 $sql .= " AND er.busy = 1";
1308 $sql .= " AND (";
1309
1310 // event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
1311 $sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
1312 // event date end between ac.datep and ac.datep2
1313 if (!empty($eventDateEnd)) {
1314 $sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
1315 }
1316 // event date start before ac.datep and event date end after ac.datep2
1317 $sql .= " OR (";
1318 $sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
1319 if (!empty($eventDateEnd)) {
1320 $sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
1321 }
1322 $sql .= ")";
1323
1324 $sql .= ")";
1325 $resql = $db->query($sql);
1326 if (!$resql) {
1327 $error++;
1328 $object->error = $db->lasterror();
1329 $object->errors[] = $object->error;
1330 } else {
1331 if ($db->num_rows($resql) > 0) {
1332 // Resource already in use
1333 $error++;
1334 $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
1335 while ($obj = $db->fetch_object($resql)) {
1336 $object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
1337 }
1338 $object->errors[] = $object->error;
1339 }
1340 $db->free($resql);
1341 }
1342
1343 if ($error) {
1344 setEventMessages($object->error, $object->errors, 'errors');
1345 }
1346 }
1347 }
1348
1349 if (!$error) {
1350 $db->begin();
1351 $result = $object->update($user);
1352 if ($result < 0) {
1353 $error++;
1354 setEventMessages($object->error, $object->errors, 'errors');
1355 $db->rollback();
1356 } else {
1357 $db->commit();
1358 }
1359 }
1360 }
1361 if (!empty($backtopage)) {
1362 header("Location: ".$backtopage, true, 307);
1363 exit;
1364 } else {
1365 $action = '';
1366 }
1367}
1368
1369// Actions to delete doc
1370$upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref);
1371$permissiontoadd = ($user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'read')));
1372if (empty($reshook)) {
1373 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1374}
1375
1376
1377/*
1378 * View
1379 */
1380
1381$form = new Form($db);
1382$formproject = new FormProjets($db);
1383
1384$arrayrecurrulefreq = array(
1385 'no' => $langs->trans("OnceOnly"),
1386 'YEARLY' => $langs->trans("EveryYear"),
1387 'MONTHLY' => $langs->trans("EveryMonth"),
1388 'WEEKLY' => $langs->trans("EveryWeek")
1389 // 'DAILY'=>$langs->trans("EveryDay")
1390);
1391
1392
1393$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda|DE:Modul_Terminplanung';
1394llxHeader('', $langs->trans("Agenda"), $help_url);
1395
1396if ($action == 'create') {
1397 $contact = new Contact($db);
1398
1399 $socpeopleassigned = GETPOST("socpeopleassigned", 'array');
1400 if (!empty($socpeopleassigned[0])) {
1401 $result = $contact->fetch($socpeopleassigned[0]);
1402 if ($result < 0) {
1403 dol_print_error($db, $contact->error);
1404 }
1405 }
1406
1407 dol_set_focus("#label");
1408
1409 if (!empty($conf->use_javascript_ajax)) {
1410 print "\n".'<script type="text/javascript">';
1411 print '$(document).ready(function () {
1412 function setdatefields()
1413 {
1414 if ($("#fullday:checked").val() == null) {
1415 $(".fulldaystarthour").removeAttr("disabled");
1416 $(".fulldaystartmin").removeAttr("disabled");
1417 $(".fulldayendhour").removeAttr("disabled");
1418 $(".fulldayendmin").removeAttr("disabled");
1419 $("#p2").removeAttr("disabled");
1420 } else {
1421 $(".fulldaystarthour").prop("disabled", true).val("00");
1422 $(".fulldaystartmin").prop("disabled", true).val("00");
1423 $(".fulldayendhour").prop("disabled", true).val("23");
1424 $(".fulldayendmin").prop("disabled", true).val("59");
1425 $("#p2").removeAttr("disabled");
1426 }
1427 }
1428 $("#fullday").change(function() {
1429 console.log("setdatefields");
1430 setdatefields();
1431 });
1432 var old_startdate = null;
1433 $("#ap").focus(function() {
1434 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1435 });
1436 $("#ap").next(".ui-datepicker-trigger").click(function() {
1437 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1438 });
1439 $("#ap").change(function() {
1440 setTimeout(function() {
1441 if ($("#p2").val() !== "") {
1442 var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1443 var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
1444 if (new_startdate > old_enddate) {
1445 var timeDiff = old_enddate - old_startdate;
1446 var new_enddate = new Date(new_startdate.getTime() + timeDiff);
1447 $("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
1448 $("#p2day").val(new_enddate.getDate());
1449 $("#p2month").val(new_enddate.getMonth() + 1);
1450 $("#p2year").val(new_enddate.getFullYear());
1451 }
1452 }
1453 }, 0);
1454 });
1455 $("#actioncode").change(function() {
1456 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
1457 else $("#dateend").removeClass("fieldrequired");
1458 });
1459 $("#aphour,#apmin").change(function() {
1460 if ($("#actioncode").val() == \'AC_RDV\') {
1461 var oldhour = parseInt($("#aphour").val());
1462 var oldmin = parseInt($("#apmin").val());
1463 var oldday = parseInt($("#apday").val());
1464 var oldmonth = $("#apmonth").val();
1465 var oldyear = $("#apyear").val();
1466
1467 var newhour = oldhour + 1;
1468 var newday = oldday;
1469 var newmonth = oldmonth;
1470 var newyear = oldyear;
1471 if (newhour >= 24) {
1472 newhour = 0;
1473 newday = oldday + 1;
1474 }
1475 console.log("Start date was changed, we modify end date "+oldhour+" "+oldmin+" -> "+newhour+" "+oldmin);
1476 $("#p2hour").val(("00" + newhour).substr(-2,2));
1477 $("#p2min").val(("00" + oldmin).substr(-2,2));
1478 $("#p2day").val(newday);
1479 $("#p2month").val(newmonth);
1480 $("#p2year").val(newyear);
1481 $("#p2").val($("#ap").val());
1482 }
1483 });
1484 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
1485 else $("#dateend").removeClass("fieldrequired");
1486 setdatefields();
1487 })';
1488 print '</script>'."\n";
1489 }
1490
1491 print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
1492 print '<input type="hidden" name="token" value="'.newToken().'">';
1493 print '<input type="hidden" name="action" value="add">';
1494 print '<input type="hidden" name="donotclearsession" value="1">';
1495 print '<input type="hidden" name="page_y" value="">';
1496 if ($backtopage) {
1497 print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
1498 }
1499 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1500 print '<input type="hidden" name="actioncode" value="'.dol_getIdFromCode($db, 'AC_OTH', 'c_actioncomm').'">';
1501 }
1502
1503 print load_fiche_titre($langs->trans("AddAnAction"), '', 'title_agenda');
1504
1505 print dol_get_fiche_head();
1506
1507 print '<div class="divcreate">';
1508 print '<table class="border centpercent nobottom">';
1509
1510 // Title
1511 print '<tr><td'.(getDolGlobalString('AGENDA_USE_EVENT_TYPE') ? ' class="fieldrequired"' : ' class="fieldrequired titlefieldcreate"').'>'.$langs->trans("Title").'</td><td><input type="text" id="label" name="label" class="soixantepercent" value="'.GETPOST('label').'"></td></tr>';
1512
1513 // Type of event
1514 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1515 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Type").'</span></b></td><td>';
1516 $default = getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT', 'AC_OTH');
1517 if (empty($default)) {
1518 $default = 'AC_OTH';
1519 }
1520 print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
1521 $selectedvalue = GETPOSTISSET("actioncode") ? GETPOST("actioncode", 'aZ09') : ($object->type_code ? $object->type_code : $default);
1522 print $formactions->select_type_actions($selectedvalue, "actioncode", "systemauto", 0, -1, 0, 1); // TODO Replace 0 with -2 in onlyautoornot
1523 print '</td></tr>';
1524 }
1525
1526 // Full day
1527 print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td>';
1528 print '<td class="valignmiddle height30">';
1529 print '<div>';
1530 print '<input class="valignmiddle" type="checkbox" id="fullday" name="fullday" '.(GETPOST('fullday') ? ' checked' : '').'><label for="fullday" class="valignmiddle small">'.$langs->trans("EventOnFullDay").'</label>';
1531 print '</div>';
1532 print '</td></tr>';
1533
1534 $datep = ($datep ? $datep : (is_null($object->datep) ? '' : $object->datep));
1535 if (GETPOST('datep', 'alpha', 1)) {
1536 $datep = dol_stringtotime(GETPOST('datep', 'alpha', 1), 'tzuserrel');
1537 }
1538 $datef = ($datef ? $datef : $object->datef);
1539 if (GETPOST('datef', 'alpha', 1)) {
1540 $datef = dol_stringtotime(GETPOST('datef', 'alpha', 1), 'tzuserrel');
1541 }
1542 if (empty($datef) && !empty($datep)) {
1543 if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || (!getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') || getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') == '-1')) {
1544 $datef = dol_time_plus_duree($datep, getDolGlobalInt('AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS', 1), 'h');
1545 }
1546 }
1547
1548 // Date start
1549 print '<tr><td class="nowrap">';
1550 print '</td><td>';
1551 print '<div class="inline-block">';
1552 if (GETPOST("afaire") == 1) {
1553 print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel'); // Empty value not allowed for start date and hours if "todo"
1554 } else {
1555 print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel');
1556 }
1557 print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span><br class="showonsmartphone"> ';
1558 print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel');
1559 print '</div>';
1560
1561 //print '</td></tr>';
1562
1563 // Recurring event
1564 $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
1565 if ($userepeatevent) {
1566 //print '<tr><td></td><td>';
1567 print '<div class="clearbothonsmartphone hideonsmartphone inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>';
1568
1569 // Repeat
1570 print '<div class="inline-block small" data-html="repeat">';
1571 print '<span class="opacitymedium">';
1572 print img_picto($langs->trans("Recurrence"), 'recurring', 'style="margin-left: 3px" class="paddingright"');
1573 print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
1574
1575 $selectedrecurrulefreq = 'no';
1576 $selectedrecurrulebyyearmonthday = '';
1577 $selectedrecurrulebymonthday = '';
1578 $selectedrecurrulebyday = '';
1579 $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
1580 $object->recurrule .= GETPOSTISSET('BYYEARMONTHDAY') ? "_BYYEARMONTHDAY".GETPOST('BYYEARMONTHDAY', 'alpha') : "";
1581 $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
1582 $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
1583
1584
1585 $reg = [];
1586 if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
1587 $selectedrecurrulefreq = $reg[1];
1588 }
1589 if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
1590 $selectedrecurrulebyyearmonthday = (int) $reg[1];
1591 }
1592 if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
1593 $selectedrecurrulebymonthday = (int) $reg[1];
1594 }
1595 if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
1596 $selectedrecurrulebyday = (int) $reg[1];
1597 }
1598
1599 print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly minwidth125 maxwidth150');
1600 print '</span>';
1601 // print '<script>console.log("recurrule: " +'.$object->recurrule.')</script>';
1602 // For recursive event
1603
1604
1605 // If recurrulefreq is MONTHLY
1606 /*
1607 print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
1608 print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
1609 print '</div>';
1610 // If recurrulefreq is WEEKLY
1611 print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
1612 print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
1613 print '</div>';
1614 */
1615
1616 // limit date
1617 $repeateventlimitdate = empty($repeateventlimitdate) ? (dol_now() + ((24 * 3600 * 365) + 1)) : $repeateventlimitdate;
1618
1619 print '<div class="hidden marginrightonly inline-block repeateventlimitdate">';
1620 print $langs->trans("Until")." ";
1621 print $form->selectDate($repeateventlimitdate, 'limit', 0, 0, 0, "action", 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
1622 print '</div>';
1623 ?>
1624 <script type="text/javascript">
1625 jQuery(document).ready(function() {
1626 function init_repeat() {
1627 console.log("recurrule: " + "<?php echo $object->recurrule; ?>");
1628 console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>");
1629 console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>");
1630 console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>");
1631 console.log("reg4: " + "<?php echo $selectedrecurrulebyyearmonthday; ?>");
1632 console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>");
1633 if (jQuery("#recurrulefreq").val() == 'YEARLY') {
1634 /* jQuery(".repeateventBYYEARMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1635 jQuery(".repeateventlimitdate").css("display", "inline-block");
1636 jQuery(".repeateventBYMONTHDAY").hide();
1637 jQuery(".repeateventBYDAY").hide();
1638 } else if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
1639 /* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1640 jQuery(".repeateventlimitdate").css("display", "inline-block");
1641 jQuery(".repeateventBYYEARMONTHDAY").hide();
1642 jQuery(".repeateventBYDAY").hide();
1643 } else if (jQuery("#recurrulefreq").val() == 'WEEKLY') {
1644 jQuery(".repeateventBYYEARMONTHDAY").hide();
1645 jQuery(".repeateventBYMONTHDAY").hide();
1646 /* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1647 jQuery(".repeateventlimitdate").css("display", "inline-block");
1648 } else {
1649 jQuery(".repeateventBYYEARMONTHDAY").hide();
1650 jQuery(".repeateventBYMONTHDAY").hide();
1651 jQuery(".repeateventBYDAY").hide();
1652 jQuery(".repeateventlimitdate").hide();
1653 }
1654 }
1655 init_repeat();
1656 jQuery("#recurrulefreq").change(function() {
1657 init_repeat();
1658 });
1659 });
1660 </script>
1661 <?php
1662 print '</div>';
1663 // print '</td></tr>';
1664 }
1665
1666 print '</td></tr>';
1667
1668
1669 // Location
1670 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
1671 print '<tr><td class="titlefieldcreate">'.$langs->trans("Location").'</td><td>';
1672 print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
1673 print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.(GETPOST('location') ? GETPOST('location') : $object->location).'"></td></tr>';
1674 }
1675
1676 print '</table>';
1677 print '</div>';
1678
1679 print '<br>';
1680
1681 print '<div class="divcreate">';
1682 print '<table class="border centpercent nobottom">';
1683
1684 // Assigned to user
1685 print '<tr><td class="nowrap titlefieldcreate"><span>';
1686 print $langs->trans("AssignedTo");
1687 print '</span></td><td>';
1688 $listofuserid = [];
1689 $listofcontactid = [];
1690 $listofotherid = [];
1691
1692 if (empty($donotclearsession)) {
1693 $assignedtouser = GETPOST("assignedtouser") ? GETPOST("assignedtouser") : (!empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : $user->id);
1694 if ($assignedtouser) {
1695 $listofuserid[$assignedtouser] = array('id' => $assignedtouser, 'mandatory' => 0); // Owner first
1696 }
1697 //$listofuserid[$user->id] = array('id'=>$user->id, 'mandatory'=>0, 'transparency'=>(GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1)); // 1 by default at first init
1698 $listofuserid[$assignedtouser]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1); // 1 by default at first init
1699 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
1700 } else {
1701 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
1702 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
1703 }
1704 if (!is_array($listofuserid)) {
1705 $listofuserid = [];
1706 }
1707 $firstelem = reset($listofuserid);
1708 if (isset($listofuserid[$firstelem['id']])) {
1709 $listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
1710 }
1711 }
1712 print '<!-- list of user to assign -->'."\n";
1713 print '<div class="assignedtouser">';
1714 print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid);
1715 print '</div>';
1716 print '</td></tr>';
1717
1718 if (isModEnabled('resource')) {
1719 // Resources
1720 print '<tr><td class="tdtop nowrap">'.$langs->trans("Resource").'</td><td>';
1721
1722 $listofresourceid = [];
1723 if (empty($donotclearsession)) {
1724 $assignedtoresource = GETPOST("assignedtoresource");
1725 if ($assignedtoresource) {
1726 $listofresourceid[$assignedtoresource] = array('id' => $assignedtoresource, 'mandatory' => 0); // Owner first
1727 }
1728 $_SESSION[$sessionkeyassignedtoresource] = json_encode($listofresourceid);
1729 } else {
1730 if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
1731 $listofresourceid = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
1732 }
1733 if (!is_array($listofresourceid)) {
1734 $listofresourceid = [];
1735 }
1736 $firstelem = reset($listofresourceid);
1737 if ($firstelem && isset($listofresourceid[$firstelem['id']])) {
1738 $listofresourceid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
1739 }
1740 }
1741 print '<div class="assignedtoresource">';
1742 print $form->select_dolresources_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtoresource', 1, [], 0, '', [], '0', 0, 0, 'AND u.statut != 0', 1, $listofresourceid);
1743 print '</div>';
1744 print '</td></tr>';
1745 }
1746
1747 if (isModEnabled('category')) {
1748 // Categories
1749 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1750 print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
1751 print "</td></tr>";
1752 }
1753
1754 print '</table>';
1755 print '</div>';
1756
1757
1758 print '<br>';
1759
1760 print '<div class="divcreate">';
1761 print '<table class="border centpercent nobottom">';
1762
1763 // Status
1764 print '<tr><td>'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td>';
1765 print '<td>';
1766 $percent = $complete !== '' ? $complete : -1;
1767 if (GETPOSTISSET('status')) {
1768 $percent = GETPOST('status');
1769 } elseif (GETPOSTISSET('percentage')) {
1770 $percent = GETPOSTINT('percentage');
1771 } else {
1772 if ($complete == '0' || GETPOST("afaire") == 1) {
1773 $percent = '0';
1774 } elseif ($complete == 100 || GETPOST("afaire") == 2) {
1775 $percent = 100;
1776 }
1777 }
1778 print $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300', 1);
1779 print '</td></tr>';
1780
1781 if (isModEnabled("societe")) {
1782 // Related company
1783 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ActionOnCompany").'</td><td>';
1784 if (GETPOSTINT('socid') > 0) {
1785 $societe = new Societe($db);
1786 $societe->fetch(GETPOSTINT('socid'));
1787 print $societe->getNomUrl(1);
1788 print '<input type="hidden" id="socid" name="socid" value="'.GETPOSTINT('socid').'">';
1789 } else {
1790 $events = [];
1791 $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
1792 //For external user force the company to user company
1793 if (!empty($user->socid)) {
1794 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($user->socid, 'socid', '', 1, 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1795 } else {
1796 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '', $langs->trans('SelectThirdParty'), 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1797 }
1798 }
1799 print '</td></tr>';
1800
1801 // Related contact
1802 print '<tr><td class="nowrap">'.$langs->trans("ActionOnContact").'</td><td>';
1803 $preselectedids = GETPOST('socpeopleassigned', 'array:int');
1804 if (GETPOSTINT('contactid')) {
1805 $preselectedids[GETPOSTINT('contactid')] = GETPOSTINT('contactid');
1806 }
1807 if ($origin == 'contact') {
1808 $preselectedids[GETPOSTINT('originid')] = GETPOSTINT('originid');
1809 }
1810 // select "all" or "none" contact by default
1811 if (getDolGlobalInt('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT')) {
1812 // Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
1813 $select_contact_default = 0; // select "all" contacts by default : avoid to use it if there is a lot of contacts
1814 } else {
1815 $select_contact_default = -1; // select "none" by default
1816 }
1817 print img_picto('', 'contact', 'class="pictofixedwidth"');
1818
1819 if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
1820 // FIXME Use a select without the "multiple" (not supported when CONTACT_USE_SEARCH_TO_SELECT is on) or allow use only when $object->socid is set...
1821 /*
1822 $selected = array_keys($object->socpeopleassigned);
1823 print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
1824 */
1825 $sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
1826 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
1827 print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
1828 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
1829 } else {
1830 print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
1831 }
1832
1833 print '</td></tr>';
1834 }
1835
1836 // Project
1837 if (isModEnabled('project')) {
1838 $langs->load("projects");
1839
1840 $projectid = GETPOSTINT('projectid');
1841
1842 print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td id="project-input-container">';
1843 print img_picto('', 'project', 'class="pictofixedwidth"');
1844 print $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), (string) $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx maxwidth500');
1845
1846 print '&nbsp;<a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(empty($societe->id) ? '' : $societe->id).'&action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">';
1847 print '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>';
1848 $urloption = '?action=create&donotclearsession=1';
1849 $url = dol_buildpath('comm/action/card.php', 2).$urloption;
1850
1851 // update task list
1852 ?>
1853 <script type="text/javascript">
1854 $(document).ready(function () {
1855 $("#projectid").change(function () {
1856 var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
1857 console.log("Call url to get the new list of tasks: "+url);
1858 $.get(url, function(data) {
1859 console.log(data);
1860 if (data) $("#taskid").html(data).select2();
1861 })
1862 });
1863 });
1864 </script>
1865 <?php
1866
1867 print '</td></tr>';
1868
1869 // Task
1870 print '<tr><td class="titlefieldcreate">'.$langs->trans("Task").'</td><td id="project-task-input-container" >';
1871 print img_picto('', 'projecttask', 'class="pictofixedwidth"');
1872 $projectsListId = '';
1873 if (!empty($projectid)) {
1874 $projectsListId = $projectid;
1875 }
1876
1877 $tid = GETPOSTISSET("projecttaskid") ? GETPOSTINT("projecttaskid") : (GETPOSTISSET("taskid") ? GETPOSTINT("taskid") : '');
1878
1879 if (empty($projectsListId)) {
1880 print '<select class="valignmiddle flat maxwidth500 widthcentpercentminusxx minwidth150imp" id="taskid" name="taskid">';
1881 print '<option class="opacitymedium">&nbsp;</option>';
1882 print '<option class="opacitymedium" disabled data-html="'.dolPrintHTMLForAttribute($langs->trans("SelectAProjectFirst")).'">'.$langs->trans("SelectAProjectFirst").'</option>';
1883 print '</select>';
1884 print ajax_combobox('taskid');
1885 } else {
1886 print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
1887 }
1888 print '</td></tr>';
1889 }
1890
1891 // Object linked
1892 if (!empty($origin) && !empty($originid)) {
1893 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1894
1895 $hasPermissionOnLinkedObject = 0;
1896
1897 $elProp = getElementProperties($origin);
1898 $modulecodetouseforpermissioncheck = $elProp['module'];
1899 // Keep permission check aligned with rights class aliases (see restrictedArea()).
1900 $submodulecodetouseforpermissioncheck = $elProp['subelement'];
1901
1902 switch ($modulecodetouseforpermissioncheck) {
1903 case 'productbatch':
1904 $modulecodetouseforpermissioncheck = 'produit';
1905 break;
1906 case 'eventorganization':
1907 // Event organization relies on Project permissions
1908 $modulecodetouseforpermissioncheck = 'projet';
1909 $submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
1910 break;
1911 default:
1912 // No mapping needed, keep original values
1913 break;
1914 }
1915
1916 if ($user->hasRight($modulecodetouseforpermissioncheck, 'read') || $user->hasRight($modulecodetouseforpermissioncheck, $elProp['element'], 'read')) {
1917 $hasPermissionOnLinkedObject = 1;
1918 }
1919 //var_dump('origin='.$origin.' originid='.$originid.' hasPermissionOnLinkedObject='.$hasPermissionOnLinkedObject);
1920
1921 if (! in_array($origin, array('societe', 'project', 'project_task', 'user'))) {
1922 // We do not use link for object that already contains a hard coded field to make links with agenda events
1923 print '<tr><td class="titlefieldcreate">'.$langs->trans("LinkedObject").'</td>';
1924 print '<td colspan="3">';
1925 if ($hasPermissionOnLinkedObject) {
1926 print dolGetElementUrl($originid, $origin, 1);
1927 print '<input type="hidden" name="fk_element" value="'.$originid.'">';
1928 print '<input type="hidden" name="elementtype" value="'.$origin.'">';
1929 print '<input type="hidden" name="originid" value="'.$originid.'">';
1930 print '<input type="hidden" name="origin" value="'.$origin.'">';
1931 } else {
1932 print '<!-- no permission on object to link '.$origin.' id '.$originid.' -->';
1933 }
1934 print '</td></tr>';
1935 }
1936 }
1937
1938 // Priority
1939 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
1940 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td colspan="3">';
1941 print '<input type="text" name="priority" value="'.(GETPOSTISSET('priority') ? GETPOSTINT('priority') : ($object->priority ? $object->priority : '')).'" size="5">';
1942 print '</td></tr>';
1943 }
1944
1945 // Description
1946 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
1947 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1948 $doleditor = new DolEditor('note', (GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : $object->note_private), '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
1949 $doleditor->Create();
1950 print '</td></tr>';
1951
1952 // Other attributes
1953 $parameters = [];
1954 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1955 print $hookmanager->resPrint;
1956 if (empty($reshook)) {
1957 print $object->showOptionals($extrafields, 'create', $parameters);
1958 }
1959
1960 print '</table>';
1961 print '</div>';
1962
1963 if ($enablereminders) {
1964 //checkbox create reminder
1965 print '<hr>';
1966
1967 print '<label for="addreminder">'.img_picto('', 'bell', 'class="pictofixedwidth"').$langs->trans("AddReminder").'</label> <input type="checkbox" id="addreminder" name="addreminder"'.(empty(GETPOST('addreminder')) ? '' : 'checked').'><br>';
1968
1969 print '<div class="reminderparameters" '.(empty(GETPOST('addreminder')) ? 'style="display: none;' : '').' ">';
1970 print '<br>';
1971
1972 print '<table class="border centpercent">';
1973
1974 //Reminder
1975 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
1976 print '<input class="width50" type="number" name="offsetvalue" value="'.(GETPOSTISSET('offsetvalue') ? GETPOSTINT('offsetvalue') : getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30)).'"> ';
1977
1978 print $form->selectTypeDuration('offsetunit', (empty($offsetunit) ? 'i' : $offsetunit), $TDurationTypesExcluded);
1979 print '</td></tr>';
1980
1981 //Reminder Type
1982 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
1983 print $form->selectarray('selectremindertype', $TRemindTypes, '', 0, 0, 0, '', 0, 0, 0, '', 'minwidth200 maxwidth500', 1);
1984 print '</td></tr>';
1985
1986 //Mail Model
1987 if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
1988 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
1989 print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (empty($modelmail) ? 0 : $modelmail));
1990 print '</td></tr>';
1991 }
1992
1993 print '</table>';
1994 print '</div>';
1995
1996 $reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
1997 $reminderDefaultOffset = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
1998 $reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
1999 $reminderDefaultEmailModel = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
2000
2001 print "\n".'<script type="text/javascript">';
2002 print '$(document).ready(function () {
2003 const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
2004 $("#actioncode").change(function(){
2005 var selected_event_type = $("#actioncode option:selected").val();
2006
2007 if (reminderDefaultEventTypes.includes(selected_event_type)) {
2008 $(".reminderparameters").show();
2009 $("#addreminder").prop("checked", true);
2010
2011 // Set period with default reminder period
2012 $("[name=\"offsetvalue\"]").val(\'' . dol_escape_js((string) $reminderDefaultOffset) . '\');
2013 $("#select_offsetunittype_duration").select2("destroy");
2014 $("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
2015 $("#select_offsetunittype_duration").select2();
2016
2017 $("#selectremindertype").select2("destroy");
2018 $("#selectremindertype").val("email");
2019 $("#selectremindertype").select2();
2020
2021 // Set default reminder mail model
2022 $("#select_actioncommsendmodel_mail").closest("tr").show();
2023 $("#select_actioncommsendmodel_mail").select2("destroy");
2024 $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js((string) $reminderDefaultEmailModel).'\');
2025 $("#select_actioncommsendmodel_mail").select2();
2026 }
2027 });
2028 })';
2029 print '</script>'."\n";
2030
2031 print "\n".'<script type="text/javascript">';
2032 print '$(document).ready(function () {
2033 function toggle_reminder_part(evt) {
2034 console.log("Toggle reminder part");
2035 if ($("#addreminder").is(":checked")) {
2036 $(".reminderparameters").show();
2037 } else {
2038 $(".reminderparameters").hide();
2039 }
2040 $("#selectremindertype").select2("destroy");
2041 $("#selectremindertype").select2();
2042 $("#select_offsetunittype_duration").select2("destroy");
2043 $("#select_offsetunittype_duration").select2();
2044 selectremindertype();
2045 });
2046
2047 toggle_reminder_part();
2048 $("#addreminder").click(toggle_reminder_part);
2049
2050 $("#selectremindertype").change(function(){
2051 selectremindertype();
2052 });
2053
2054 function selectremindertype() {
2055 console.log("Call selectremindertype");
2056 var selected_option = $("#selectremindertype option:selected").val();
2057 if(selected_option == "email") {
2058 $("#select_actioncommsendmodel_mail").closest("tr").show();
2059 } else {
2060 $("#select_actioncommsendmodel_mail").closest("tr").hide();
2061 }
2062 }
2063
2064 })';
2065 print '</script>'."\n";
2066 }
2067
2068 print dol_get_fiche_end();
2069
2070 print $form->buttonsSaveCancel("Create");
2071
2072 print "</form>";
2073}
2074
2075// View or edit
2076if ($id > 0 && $action != 'create') {
2077 $result1 = $object->fetch($id);
2078 if ($result1 <= 0) {
2079 recordNotFound('', 0);
2080 }
2081
2082 $result2 = $object->fetch_thirdparty();
2083 $result2 = $object->fetchProject();
2084 $result3 = $object->fetch_contact();
2085 $result4 = $object->fetch_userassigned();
2086 $result5 = $object->fetch_optionals();
2087
2088 if ($listUserAssignedUpdated || $donotclearsession) {
2089 $percentage = in_array(GETPOST('status'), array(-1, 100)) ? GETPOST('status') : (in_array($complete, array(-1, 100)) ? $complete : GETPOSTINT("percentage")); // If status is -1 or 100, percentage is not defined and we must use status
2090
2091 $datep = dol_mktime($fulldayevent ? 0 : $aphour, $fulldayevent ? 0 : $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
2092 $datef = dol_mktime($fulldayevent ? 23 : $p2hour, $fulldayevent ? 59 : $p2min, $fulldayevent ? 59 : 0, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
2093
2094 $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm');
2095 $object->label = GETPOST("label", "alphanohtml");
2096 $object->datep = $datep;
2097 $object->datef = $datef;
2098 $object->percentage = $percentage;
2099 $object->priority = GETPOSTINT("priority");
2100 $object->fulldayevent = GETPOST("fullday") ? 1 : 0;
2101 $object->location = GETPOST('location', "alphanohtml");
2102 $object->socid = GETPOSTINT("socid");
2103 $socpeopleassigned = GETPOST("socpeopleassigned", 'array');
2104 foreach ($socpeopleassigned as $tmpid) {
2105 $object->socpeopleassigned[$id] = array('id' => $tmpid);
2106 }
2107 $object->contact_id = GETPOSTINT("contactid");
2108 $object->fk_project = GETPOSTINT("projectid");
2109
2110 $object->note_private = GETPOST("note", 'restricthtml');
2111 }
2112
2113 if ($result2 < 0 || $result3 < 0 || $result4 < 0 || $result5 < 0) {
2114 dol_print_error($db, $object->error);
2115 exit;
2116 }
2117
2118
2119 /*
2120 * Show tabs
2121 */
2122
2123 $head = actions_prepare_head($object);
2124
2125 $now = dol_now();
2126 $delay_warning = getDolGlobalInt('MAIN_DELAY_ACTIONS_TODO') * 24 * 60 * 60;
2127
2128
2129 // Deletion confirmation action
2130 if ($action == 'delete') {
2131 print $form->formconfirm("card.php?id=".urlencode((string) ($id)), $langs->trans("DeleteAction"), $langs->trans("ConfirmDeleteAction"), "confirm_delete", '', '', 1);
2132 }
2133
2134 if ($action == 'edit') {
2135 $caneditdateorowner = ($object->type != 'systemauto');
2136
2137 if (!empty($conf->use_javascript_ajax)) {
2138 print "\n".'<script type="text/javascript">';
2139 print '$(document).ready(function () {
2140 function setdatefields()
2141 {
2142 if ($("#fullday:checked").val() == null) {
2143 $(".fulldaystarthour").removeAttr("disabled");
2144 $(".fulldaystartmin").removeAttr("disabled");
2145 $(".fulldayendhour").removeAttr("disabled");
2146 $(".fulldayendmin").removeAttr("disabled");
2147 } else {
2148 $(".fulldaystarthour").prop("disabled", true).val("00");
2149 $(".fulldaystartmin").prop("disabled", true).val("00");
2150 $(".fulldayendhour").prop("disabled", true).val("23");
2151 $(".fulldayendmin").prop("disabled", true).val("59");
2152 }
2153 }
2154
2155 '.($caneditdateorowner ? ' setdatefields();' : '').'
2156
2157 $("#fullday").change(function() {
2158 setdatefields();
2159 });
2160 var old_startdate = null;
2161 $("#ap").focus(function() {
2162 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2163 });
2164 $("#ap").next(".ui-datepicker-trigger").click(function() {
2165 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2166 });
2167 $("#ap").change(function() {
2168 setTimeout(function() {
2169 if ($("#p2").val() !== "") {
2170 var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2171 var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
2172 if (new_startdate > old_enddate) {
2173 var timeDiff = old_enddate - old_startdate;
2174 var new_enddate = new Date(new_startdate.getTime() + timeDiff);
2175 $("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
2176 $("#p2day").val(new_enddate.getDate());
2177 $("#p2month").val(new_enddate.getMonth() + 1);
2178 $("#p2year").val(new_enddate.getFullYear());
2179 }
2180 }
2181 }, 0);
2182 });
2183 $("#actioncode").change(function() {
2184 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
2185 else $("#dateend").removeClass("fieldrequired");
2186 });
2187 })';
2188 print '</script>'."\n";
2189 }
2190
2191 print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
2192 print '<input type="hidden" name="token" value="'.newToken().'">';
2193 print '<input type="hidden" name="action" value="update">';
2194 print '<input type="hidden" name="id" value="'.$id.'">';
2195 print '<input type="hidden" name="ref_ext" value="'.$object->ref_ext.'">';
2196 print '<input type="hidden" name="page_y" value="">';
2197 if ($backtopage) {
2198 print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
2199 }
2200 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE') && ! preg_match('/^TICKET_MSG_PRIVATE/', $object->code)) {
2201 print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
2202 }
2203
2204 print dol_get_fiche_head($head, 'card', $langs->trans("Action"), 0, 'action');
2205
2206 print '<table class="border tableforfield centpercent">';
2207
2208 // Ref
2209 print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>'.$object->id.'</td></tr>';
2210
2211 // Title
2212 print '<tr><td class="fieldrequired'.(!getDolGlobalString('AGENDA_USE_EVENT_TYPE') ? ' titlefieldcreate' : '').'">'.$langs->trans("Title").'</td><td><input type="text" name="label" class="soixantepercent" value="'.$object->label.'"></td></tr>';
2213
2214 // Type of event
2215 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && $object->elementtype != "ticket") {
2216 print '<tr><td class="fieldrequired">'.$langs->trans("Type").'</td><td>';
2217 if ($object->type_code != 'AC_OTH_AUTO') {
2218 print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
2219 print $formactions->select_type_actions(GETPOST("actioncode", 'aZ09') ? GETPOST("actioncode", 'aZ09') : $object->type_code, "actioncode", "systemauto", 0, 0, 0, 1);
2220 } else {
2221 print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
2222 print $object->getTypePicto();
2223 print $langs->trans("Action".$object->type_code);
2224 }
2225 print '</td></tr>';
2226 }
2227
2228 // Private
2229 if ($object->elementtype == 'ticket') {
2230 print '<tr><td>'.$langs->trans("MarkMessageAsPrivate");
2231 print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
2232 print '</td><td><input type="checkbox" id="private" name="private" '.(preg_match('/^TICKET_MSG_PRIVATE/', $object->code) ? ' checked' : '').'></td></tr>';
2233 }
2234
2235 // Full day event
2236 print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td class="valignmiddle height30 small">';
2237 print '<input '.($caneditdateorowner ? '' : ' disabled').' type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
2238 print '<label for="fullday">'.$langs->trans("EventOnFullDay").'</label>';
2239
2240 // // Recurring event
2241 // $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
2242 // if ($userepeatevent) {
2243 // // Repeat
2244 // //print '<tr><td></td><td colspan="3">';
2245 // print ' &nbsp; &nbsp; &nbsp; &nbsp; <div class="opacitymedium inline-block">';
2246 // print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
2247 // print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
2248 // $selectedrecurrulefreq = 'no';
2249 // $selectedrecurrulebymonthday = '';
2250 // $selectedrecurrulebyday = '';
2251 // if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
2252 // $selectedrecurrulefreq = $reg[1];
2253 // }
2254 // if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
2255 // $selectedrecurrulebymonthday = $reg[1];
2256 // }
2257 // if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
2258 // $selectedrecurrulebyday = $reg[1];
2259 // }
2260 // print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
2261 // // If recurrulefreq is MONTHLY
2262 // print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
2263 // print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
2264 // print '</div>';
2265 // // If recurrulefreq is WEEKLY
2266 // print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
2267 // print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
2268 // print '</div>';
2269 // print '<script type="text/javascript">
2270 // jQuery(document).ready(function() {
2271 // function init_repeat()
2272 // {
2273 // if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
2274 // {
2275 // jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
2276 // jQuery(".repeateventBYDAY").hide();
2277 // }
2278 // else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
2279 // {
2280 // jQuery(".repeateventBYMONTHDAY").hide();
2281 // jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
2282 // }
2283 // else
2284 // {
2285 // jQuery(".repeateventBYMONTHDAY").hide();
2286 // jQuery(".repeateventBYDAY").hide();
2287 // }
2288 // }
2289 // init_repeat();
2290 // jQuery("#recurrulefreq").change(function() {
2291 // init_repeat();
2292 // });
2293 // });
2294 // </script>';
2295 // print '</div>';
2296 // //print '</td></tr>';
2297 // }
2298 print '</td></tr>';
2299
2300 // Date start - end
2301 print '<tr><td class="nowrap">';
2302 print '</td><td>';
2303 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2304 print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 2, ($caneditdateorowner ? 0 : 1), 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
2305 print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span> ';
2306 print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 2, ($caneditdateorowner ? 0 : 1), 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
2307 print '</td></tr>';
2308
2309 // Location
2310 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2311 print '<tr><td>'.$langs->trans("Location").'</td><td>';
2312 print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
2313 print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.$object->location.'"></td></tr>';
2314 }
2315
2316 print '<tr class="tdsmallheight"><td class="tdsmallheight">&nbsp;</td><td class="tdsmallheight"></td></tr>';
2317
2318 // Assigned to
2319 $listofuserid = []; // User assigned
2320 if (empty($donotclearsession)) {
2321 if ($object->userownerid > 0) {
2322 $listofuserid[$object->userownerid] = array(
2323 'id' => $object->userownerid,
2324 'type' => 'user',
2325 //'transparency'=>$object->userassigned[$user->id]['transparency'],
2326 'transparency' => $object->transparency, // Force transparency on ownerfrom event
2327 'answer_status' => (isset($object->userassigned[$object->userownerid]['answer_status']) ? $object->userassigned[$object->userownerid]['answer_status'] : null),
2328 'mandatory' => (isset($object->userassigned[$object->userownerid]['mandatory']) ? $object->userassigned[$object->userownerid]['mandatory'] : null)
2329 );
2330 }
2331 if (!empty($object->userassigned)) { // Now concat assigned users
2332 // Restore array with key with same value than param 'id'
2333 $tmplist1 = $object->userassigned;
2334 foreach ($tmplist1 as $key => $val) {
2335 if ($val['id'] && $val['id'] != $object->userownerid) {
2336 $listofuserid[$val['id']] = $val;
2337 }
2338 }
2339 }
2340 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
2341 } else {
2342 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
2343 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
2344 }
2345 }
2346
2347 $listofcontactid = $object->socpeopleassigned; // Contact assigned
2348 $listofotherid = $object->otherassigned; // Other undefined email (not used yet)
2349
2350 print '<tr><td class="nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
2351 print '<div class="assignedtouser">';
2352 print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner);
2353 print '</div>';
2354 /*if (in_array($user->id,array_keys($listofuserid)))
2355 {
2356 print '<div class="myavailability">';
2357 print $langs->trans("MyAvailability").': <input id="transparency" type="checkbox" name="transparency"'.($listofuserid[$user->id]['transparency']?' checked':'').'>'.$langs->trans("Busy");
2358 print '</div>';
2359 }*/
2360 print '</td></tr>';
2361
2362 // Tags-Categories
2363 if (isModEnabled('category')) {
2364 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
2365 print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
2366 print "</td></tr>";
2367 }
2368
2369 print '</table>';
2370
2371
2372 print '<br>';
2373
2374
2375 print '<table class="border tableforfield centpercent">';
2376
2377 // Status
2378 print '<tr><td class="nowrap">'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td><td colspan="3">';
2379 $percent = GETPOSTISSET("percentage") ? GETPOSTINT("percentage") : $object->percentage;
2380 $formactions->form_select_status_action('formaction', (string) $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300');
2381 print '</td></tr>';
2382
2383 if (isModEnabled("societe")) {
2384 // Related company
2385 print '<tr><td class="titlefieldcreate">'.$langs->trans("ActionOnCompany").'</td>';
2386 print '<td>';
2387 print '<div>';
2388 $events = []; // 'method'=parameter action of url, 'url'=url to call that return new list of contacts
2389 $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
2390 // TODO Refresh also list of project if conf PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY not defined with list linked to socid ?
2391 // FIXME If we change company, we may get a project that does not match
2392 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($object->socid, 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300');
2393 print '</div>';
2394 print '</td></tr>';
2395
2396 // Related contact
2397 print '<tr><td>'.$langs->trans("ActionOnContact").'</td><td>';
2398 print '<div class="maxwidth200onsmartphone">';
2399
2400 print img_picto('', 'contact', 'class="paddingrightonly"');
2401 if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
2402 // FIXME Use the select_contact supporting the "multiple"
2403 /*
2404 $selected = array_keys($object->socpeopleassigned);
2405 print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
2406 */
2407 $sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
2408 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
2409 print $form->selectcontacts(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : ($object->socid > 0 ? $object->socid : -1), array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', 0, 0, 0, [], 'multiple', 'contactid');
2410 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
2411 } else {
2412 // Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
2413 print $form->selectcontacts(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', 0, 0, 0, [], 'multiple', 'contactid');
2414 }
2415 print '</div>';
2416 print '</td>';
2417 print '</tr>';
2418 }
2419
2420 // Project
2421 if (isModEnabled('project')) {
2422 $langs->load("projects");
2423
2424 print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td>';
2425 print img_picto('', 'project', 'class="pictofixedwidth"');
2426 $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), (string) $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth500 widthcentpercentminusxx');
2427 if ($numprojet == 0) {
2428 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$object->socid.'&action=create&token='.newToken().'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>';
2429 }
2430 print '</td></tr>';
2431 }
2432
2433 // Priority
2434 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
2435 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td>';
2436 print '<input type="text" name="priority" value="'.($object->priority ? $object->priority : '').'" size="5">';
2437 print '</td></tr>';
2438 }
2439
2440 // Object linked
2441 if ($object->fk_project || (!empty($object->elementid) && !empty($object->elementtype))) {
2442 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2443 print '<tr>';
2444 print '<td>'.$langs->trans("LinkedObject").'</td>';
2445
2446 if ($object->elementtype == 'project_task' && isModEnabled('project')) {
2447 print '<td id="project-task-input-container" >';
2448
2449 $urloption = '?action=create&donotclearsession=1'; // we use create not edit for more flexibility
2450 $url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption;
2451
2452 // update task list
2453 ?>
2454 <script type="text/javascript" >
2455 $(document).ready(function () {
2456 $("#projectid").change(function () {
2457 var url = "<?php echo $url; ?>&projectid="+$("#projectid").val();
2458 $.get(url, function(data) {
2459 console.log($( data ).find("#fk_element").html());
2460 if (data) $("#fk_element").html( $( data ).find("#taskid").html() ).select2();
2461 })
2462 });
2463 });
2464 </script>
2465 <?php
2466
2467 print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $object->elementid, 'fk_element', 64, 0, '', 1, 0, 0, 'maxwidth500', (string) $object->fk_project, 'all', null, 1);
2468 print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
2469
2470 print '</td>';
2471 } else {
2472 if (empty($object->elementtype) && empty($object->elementid) && $object->fk_project) {
2473 $projectsListId = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : $object->fk_project;
2474
2475 print '<td id="project-task-input-container" >';
2476
2477 // update task list
2478 ?>
2479 <script type="text/javascript">
2480 $(document).ready(function () {
2481 $("#projectid").change(function () {
2482 var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
2483 console.log("Call url to get new list of tasks: "+url);
2484 $.get(url, function(data) {
2485 console.log(data);
2486 if (data) $("#taskid").html(data).select2();
2487 })
2488 });
2489 });
2490 </script>
2491 <?php
2492
2493 $tid = '';
2494 if (GETPOSTISSET("projecttaskid") && GETPOSTINT("projecttaskid") > 0) {
2495 $tid = GETPOSTINT("projecttaskid");
2496 } elseif (GETPOSTISSET("taskid") && GETPOSTINT("taskid") > 0) {
2497 $tid = GETPOSTINT("taskid");
2498 }
2499
2500 print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
2501
2502 print '</td>';
2503 } else {
2504 print '<td>';
2505 print dolGetElementUrl($object->elementid, $object->elementtype, 1);
2506 print '<input type="hidden" name="fk_element" value="'.$object->elementid.'">';
2507 print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
2508 print '</td>';
2509 }
2510 }
2511
2512 print '</tr>';
2513 }
2514
2515 // Description
2516 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
2517 // Wysiwyg editor
2518 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
2519 $doleditor = new DolEditor('note', $object->note_private, '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
2520 $doleditor->Create();
2521 print '</td></tr>';
2522
2523 // Other attributes
2524 $parameters = [];
2525 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2526 print $hookmanager->resPrint;
2527 if (empty($reshook)) {
2528 print $object->showOptionals($extrafields, 'edit', $parameters);
2529 }
2530
2531 print '</table>';
2532
2533 // Reminders
2534 if ($enablereminders) {
2535 $filteruserid = $user->id;
2536 if ($user->hasRight('agenda', 'allactions', 'read')) {
2537 $filteruserid = 0;
2538 }
2539 $object->loadReminders('', $filteruserid, false);
2540
2541 print '<hr>';
2542
2543 if (count($object->reminders) > 0) {
2544 $checked = 'checked';
2545 $keys = array_keys($object->reminders);
2546 $firstreminderId = array_shift($keys);
2547
2548 $actionCommReminder = $object->reminders[$firstreminderId];
2549 } else {
2550 $checked = '';
2551 $actionCommReminder = new ActionCommReminder($db);
2552 $actionCommReminder->offsetvalue = getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30);
2553 $actionCommReminder->offsetunit = 'i';
2554 $actionCommReminder->typeremind = 'email';
2555 }
2556 $disabled = '';
2557 /*
2558 if ($object->datep < dol_now()) {
2559 //$disabled = 'disabled title="'.dol_escape_htmltag($langs->trans("EventExpired")).'"';
2560 }
2561 */
2562
2563 print '<label for="addreminder">'.img_picto('', 'bell', 'class="pictofixedwidth"').$langs->trans("AddReminder").'</label> <input type="checkbox" id="addreminder" name="addreminder"'.($checked ? ' '.$checked : '').($disabled ? ' '.$disabled : '').'><br>';
2564
2565 print '<div class="reminderparameters" '.(empty($checked) ? 'style="display: none;"' : '').'>';
2566
2567 print '<br>';
2568
2569 print '<table class="border centpercent">';
2570
2571 // Reminder
2572 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
2573 print '<input type="number" name="offsetvalue" class="width50" value="'.$actionCommReminder->offsetvalue.'"> ';
2574 print $form->selectTypeDuration('offsetunit', $actionCommReminder->offsetunit, $TDurationTypesExcluded);
2575 print '</td></tr>';
2576
2577 // Reminder Type
2578 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
2579 print $form->selectarray('selectremindertype', $TRemindTypes, $actionCommReminder->typeremind, 0, 0, 0, '', 0, 0, 0, '', 'minwidth200', 1);
2580 print '</td></tr>';
2581
2582 $hide = '';
2583 if ($actionCommReminder->typeremind == 'browser') {
2584 $hide = 'style="display:none;"';
2585 }
2586
2587 // Mail Model
2588 if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2589 print '<tr '.$hide.'><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
2590 print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (string) $actionCommReminder->fk_email_template);
2591 print '</td></tr>';
2592 }
2593
2594 print '</table>';
2595 ?>
2596 <script type="text/javascript">
2597 $(document).ready(function () {
2598 $("#addreminder").click(function(){
2599 if (this.checked) {
2600 $(".reminderparameters").show();
2601 } else {
2602 $(".reminderparameters").hide();
2603 }
2604 });
2605 $("#selectremindertype").change(function(){
2606 var selected_option = $("#selectremindertype option:selected").val();
2607 if(selected_option == "email") {
2608 $("#select_actioncommsendmodel_mail").closest("tr").show();
2609 } else {
2610 $("#select_actioncommsendmodel_mail").closest("tr").hide();
2611 }
2612 });
2613 });
2614 </script>
2615 <?php
2616
2617 $reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
2618 $reminderDefaultOffset = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
2619 $reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
2620 $reminderDefaultEmailModel = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
2621
2622 print "\n".'<script type="text/javascript">';
2623 print '$(document).ready(function () {
2624 const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
2625 $("#actioncode").change(function(){
2626 var selected_event_type = $("#actioncode option:selected").val();
2627
2628 if (reminderDefaultEventTypes.includes(selected_event_type)) {
2629 $(".reminderparameters").show();
2630 $("#addreminder").prop("checked", true);
2631
2632 // Set period with default reminder period
2633 $("#offsetvalue").val(\''.dol_escape_js($reminderDefaultOffset).'\');
2634 $("#select_offsetunittype_duration").select2("destroy");
2635 $("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
2636 $("#select_offsetunittype_duration").select2();
2637
2638 $("#selectremindertype").select2("destroy");
2639 $("#selectremindertype").val("email");
2640 $("#selectremindertype").select2();
2641
2642 // Set default reminder mail model
2643 $("#select_actioncommsendmodel_mail").closest("tr").show();
2644 $("#select_actioncommsendmodel_mail").select2("destroy");
2645 $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js($reminderDefaultEmailModel).'\');
2646 $("#select_actioncommsendmodel_mail").select2();
2647 }
2648 });
2649 })';
2650 print '</script>'."\n";
2651 print '</div>'; // End of div for reminderparameters
2652 }
2653
2654 print dol_get_fiche_end();
2655
2656 print $form->buttonsSaveCancel();
2657
2658 print '</form>';
2659 } else {
2660 print dol_get_fiche_head($head, 'card', $langs->trans("Action"), -1, 'action');
2661
2662 $formconfirm = '';
2663
2664 // Clone event
2665 if ($action == 'clone') {
2666 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.GETPOST('id'), $langs->trans('ToClone'), $langs->trans('ConfirmCloneEvent', $object->label), 'confirm_clone', [], 'yes', 1);
2667 }
2668
2669 // Call Hook formConfirm
2670 $parameters = [];
2671 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2672 if (empty($reshook)) {
2673 $formconfirm .= $hookmanager->resPrint;
2674 } elseif ($reshook > 0) {
2675 $formconfirm = $hookmanager->resPrint;
2676 }
2677
2678 // Print form confirm
2679 print $formconfirm;
2680
2681 $linkback = '';
2682 // Link to other agenda views
2683 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&restore_lastsearch_values=1">';
2684 $linkback .= img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="pictoactionview pictofixedwidth"');
2685 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("BackToList").'</span>';
2686 $linkback .= '</a>';
2687 $linkback .= '</li>';
2688 $linkback .= '<li class="noborder litext">';
2689 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_month&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">';
2690 $linkback .= img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="pictoactionview pictofixedwidth"');
2691 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewCal").'</span>';
2692 $linkback .= '</a>';
2693 $linkback .= '</li>';
2694 $linkback .= '<li class="noborder litext">';
2695 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_week&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">';
2696 $linkback .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview pictofixedwidth"');
2697 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewWeek").'</span>';
2698 $linkback .= '</a>';
2699 $linkback .= '</li>';
2700 $linkback .= '<li class="noborder litext">';
2701 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_day&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">';
2702 $linkback .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview pictofixedwidth"');
2703 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewDay").'</span>';
2704 $linkback .= '</a>';
2705 $linkback .= '</li>';
2706 $linkback .= '<li class="noborder litext">';
2707 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/peruser.php?mode=show_peruser&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">';
2708 $linkback .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview pictofixedwidth"');
2709 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewPerUser").'</span>';
2710 $linkback .= '</a>';
2711
2712 // Add more views from hooks
2713 $parameters = [];
2714 $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
2715 if (empty($reshook)) {
2716 $linkback .= $hookmanager->resPrint;
2717 } elseif ($reshook > 1) {
2718 $linkback = $hookmanager->resPrint;
2719 }
2720
2721 //$linkback.=$out;
2722
2723 $morehtmlref = '<div class="refidno">';
2724 // Thirdparty
2725 //$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
2726 // Project
2727 if (isModEnabled('project')) {
2728 $langs->load("projects");
2729 //$morehtmlref .= '<br>';
2730 if ($usercancreate) {
2731 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2732 if ($action != 'classify') {
2733 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2734 }
2735 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
2736 } else {
2737 if (!empty($object->fk_project)) {
2738 $proj = new Project($db);
2739 $proj->fetch($object->fk_project);
2740 $morehtmlref .= $proj->getNomUrl(1);
2741 if ($proj->title) {
2742 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2743 }
2744 }
2745 }
2746 }
2747 $morehtmlref .= '</div>';
2748
2749
2750 dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'id', 'ref', $morehtmlref);
2751
2752 print '<div class="fichecenter">';
2753 print '<div class="fichehalfleft">';
2754
2755 print '<div class="underbanner clearboth"></div>';
2756
2757 // Show event in view mode
2758 print '<table class="border tableforfield centpercent">';
2759
2760 // Type
2761 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
2762 print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td><td>';
2763 $labeltype = ($langs->transnoentities("Action".$object->type_code) != "Action".$object->type_code) ? $langs->transnoentities("Action".$object->type_code) : $object->type_label;
2764 $labeltoshow = $labeltype;
2765 if ($object->code) {
2766 $labeltoshow .= ' ('.$object->code.')';
2767 }
2768 print $object->getTypePicto('pictofixedwidth paddingright', $labeltoshow);
2769 print $labeltype;
2770 print '</td></tr>';
2771 }
2772
2773 // Full day event
2774 print '<tr><td class="titlefieldmiddle">'.$langs->trans("EventOnFullDay").'</td><td>'.yn($object->fulldayevent ? 1 : 0, 3).'</td></tr>';
2775
2776 $rowspan = 4;
2777 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2778 $rowspan++;
2779 }
2780
2781 // Date start
2782 print '<tr><td>'.$langs->trans("DateActionStart").'</td><td title="'.dol_print_date($object->datep, 'dayhoursec', 'tzuserrel').'">';
2783 // Test a date before the 27 march and one after
2784 //print dol_print_date($object->datep, 'dayhour', 'gmt');
2785 //print dol_print_date($object->datep, 'dayhour', 'tzuser');
2786 //print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
2787 if (empty($object->fulldayevent)) {
2788 print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
2789 } else {
2790 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2791 print dol_print_date($object->datep, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
2792 }
2793 if ($object->percentage == 0 && $object->datep && $object->datep < ($now - $delay_warning)) {
2794 print img_warning($langs->trans("Late"));
2795 }
2796 print '</td>';
2797 print '</tr>';
2798
2799 // Date end
2800 print '<tr><td>'.$langs->trans("DateActionEnd").'</td><td title="'.dol_print_date($object->datef, 'dayhoursec', 'tzuserrel').'">';
2801 if (empty($object->fulldayevent)) {
2802 print dol_print_date($object->datef, 'dayhour', 'tzuserrel');
2803 } else {
2804 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2805 print dol_print_date($object->datef, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
2806 }
2807 if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now - $delay_warning)) {
2808 print img_warning($langs->trans("Late"));
2809 }
2810 print '</td></tr>';
2811
2812 // Recurring event (into a series)
2813 if ($object->recurid) {
2814 print '<tr><td class="titlefieldmiddle">'.$langs->trans("RecurringEvent").'</td><td>';
2815 print img_picto($langs->trans("EventPartOfARecurringSerie", $object->recurid), 'recurring', 'class="pictofixedwidth"');
2816 $reg = [];
2817 if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) {
2818 print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
2819 }
2820 if (preg_match('/FREQ=YEARLY_BYYEARMONTHDAY(\d+)/', $object->recurrule, $reg)) {
2821 print $langs->trans("EveryYear").' <span class="opacitymedium small">('.$langs->trans("DayOfYear").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
2822 }
2823 print '</td></tr>';
2824 }
2825
2826 // Location
2827 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2828 print '<tr><td>'.$langs->trans("Location").'</td><td>'.$object->location.'</td></tr>';
2829 }
2830
2831 // Assigned to user
2832 print '<tr><td class="nowrap">'.$langs->trans("ActionAssignedTo").'</td><td>';
2833 $listofuserid = [];
2834 if (empty($donotclearsession)) {
2835 if ($object->userownerid > 0) {
2836 $listofuserid[$object->userownerid] = array(
2837 'id' => $object->userownerid,
2838 'transparency' => $object->transparency, // Force transparency on owner from property of event
2839 'answer_status' => $object->userassigned[$object->userownerid]['answer_status'],
2840 'mandatory' => $object->userassigned[$object->userownerid]['mandatory']
2841 );
2842 }
2843 if (!empty($object->userassigned)) { // Now concat assigned users
2844 // Restore array with key with same value than param 'id'
2845 $tmplist1 = $object->userassigned;
2846 foreach ($tmplist1 as $key => $val) {
2847 if ($val['id'] && $val['id'] != $object->userownerid) {
2848 $listofuserid[$val['id']] = $val;
2849 }
2850 }
2851 }
2852 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
2853 } else {
2854 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
2855 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
2856 }
2857 }
2858
2859 $listofcontactid = []; // not used yet
2860 $listofotherid = []; // not used yet
2861 print '<div class="assignedtouser">';
2862 print $form->select_dolusers_forevent('view', 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, '', ($object->datep != $object->datef) ? 1 : 0, $listofuserid, $listofcontactid, $listofotherid);
2863 print '</div>';
2864 /*
2865 if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid)))
2866 {
2867 print '<div class="myavailability">';
2868 print $langs->trans("MyAvailability").': '.(($object->userassigned[$user->id]['transparency'] > 0)?$langs->trans("Busy"):$langs->trans("Available")); // We show nothing if event is assigned to nobody
2869 print '</div>';
2870 }
2871 */
2872 print ' </td></tr>';
2873
2874 // Categories
2875 if (isModEnabled('category')) {
2876 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
2877 print $form->showCategories($object->id, Categorie::TYPE_ACTIONCOMM, 1);
2878 print "</td></tr>";
2879 }
2880
2881 print '</table>';
2882
2883 print '</div>';
2884
2885 print '<div class="fichehalfright">';
2886
2887 print '<div class="underbanner clearboth"></div>';
2888 print '<table class="border tableforfield centpercent">';
2889
2890 if (isModEnabled("societe")) {
2891 // Related company
2892 print '<tr><td class="titlefield">'.$langs->trans("ActionOnCompany").'</td>';
2893 print '<td>'.(is_object($object->thirdparty) && $object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : ('<span class="opacitymedium">'.$langs->trans("None").'</span>'));
2894 if (is_object($object->thirdparty) && $object->thirdparty->id > 0 && $object->type_code == 'AC_TEL') {
2895 if ($object->thirdparty->fetch($object->thirdparty->id)) {
2896 print "<br>".dol_print_phone($object->thirdparty->phone);
2897 }
2898 }
2899 print '</td></tr>';
2900
2901 // Related contact
2902 print '<tr><td>'.$langs->trans("ActionOnContact").'</td>';
2903 print '<td>';
2904
2905 if (!empty($object->socpeopleassigned)) {
2906 foreach ($object->socpeopleassigned as $cid => $Tab) {
2907 $contact = new Contact($db);
2908 $result = $contact->fetch($cid);
2909
2910 if ($result < 0) {
2911 dol_print_error($db, $contact->error);
2912 }
2913
2914 if ($result > 0) {
2915 print $contact->getNomUrl(1);
2916 if ($object->type_code == 'AC_TEL') {
2917 if (!empty($contact->phone_pro)) {
2918 print '('.dol_print_phone($contact->phone_pro).')';
2919 }
2920 }
2921 print '<div class="paddingright"></div>';
2922 }
2923 }
2924 } else {
2925 print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
2926 }
2927 print '</td></tr>';
2928 }
2929
2930 // Priority
2931 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
2932 print '<tr><td class="nowrap" class="titlefield">' . $langs->trans("Priority") . '</td><td>';
2933 print($object->priority ? $object->priority : '');
2934 print '</td></tr>';
2935 }
2936
2937 // Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table
2938 // for such objects because there is already a dedicated field into table llx_actioncomm.
2939 if (!empty($object->elementid) && !empty($object->elementtype) && !in_array($object->elementtype, array('societe', 'contact', 'project'))) {
2940 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2941 print '<tr><td>'.$langs->trans("LinkedObject").'</td>';
2942 $link = dolGetElementUrl($object->elementid, $object->elementtype, ($object->elementtype == 'user' ? -1 : 1));
2943 print '<td>';
2944 if (empty($link)) {
2945 print '<span class="opacitymedium">'.$langs->trans("ObjectDeleted").'</span>';
2946 } else {
2947 print $link;
2948 }
2949 print '</td></tr>';
2950 }
2951
2952 //mail information
2953 if (!empty($object->email_msgid)) {
2954 print '<tr><td>'.$langs->trans('MailTopic').'</td>';
2955 print '<td>'.dol_escape_htmltag($object->email_subject).'</td></tr>';
2956 print '<tr><td>'.$langs->trans('MailFrom').'</td>';
2957 print '<td>'.dol_escape_htmltag($object->email_from).'</td></tr>';
2958 print '<tr><td>'.$langs->trans('MailTo').'</td>';
2959 print '<td>'.dol_escape_htmltag($object->email_to).'</td></tr>';
2960 if (!empty($object->email_tocc)) {
2961 print '<tr><td>'.$langs->trans('MailCC').'</td>';
2962 print '<td>'.dol_escape_htmltag($object->email_tocc).'</td></tr>';
2963 }
2964 }
2965
2966 // Description
2967 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td class="wordbreak sensiblehtmlcontent">';
2968 print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private));
2969 print '</td></tr>';
2970
2971 // Other attributes
2972 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2973
2974 // Reminders
2975 if ($enablereminders) {
2976 $filteruserid = $user->id;
2977 if ($user->hasRight('agenda', 'allactions', 'read')) {
2978 $filteruserid = 0;
2979 }
2980 $object->loadReminders('', $filteruserid, false);
2981
2982 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Reminders").'</td><td>';
2983
2984 if (count($object->reminders) > 0) {
2985 $tmpuserstatic = new User($db);
2986
2987 foreach ($object->reminders as $actioncommreminderid => $actioncommreminder) {
2988 print $TRemindTypes[$actioncommreminder->typeremind]['label'];
2989 if ($actioncommreminder->fk_user > 0) {
2990 $tmpuserstatic->fetch($actioncommreminder->fk_user);
2991 print ' ('.$tmpuserstatic->getNomUrl(0, '', 0, 0, 16).')';
2992 }
2993 print ' - '.$actioncommreminder->offsetvalue.' '.$TDurationTypes[$actioncommreminder->offsetunit];
2994
2995 if ($actioncommreminder->status == $actioncommreminder::STATUS_TODO) {
2996 print ' - <span class="opacitymedium">';
2997 print $langs->trans("NotSent");
2998 print ' </span>';
2999 } elseif ($actioncommreminder->status == $actioncommreminder::STATUS_DONE) {
3000 print ' - <span class="opacitymedium">';
3001 print $langs->trans("Done");
3002 print ' </span>';
3003 } elseif ($actioncommreminder->status == $actioncommreminder::STATUS_ERROR) {
3004 print ' - <span class="opacitymedium">';
3005 print $form->textwithpicto($langs->trans("Error"), $actioncommreminder->lasterror);
3006 print ' </span>';
3007 }
3008 print '<br>';
3009 }
3010 }
3011
3012 print '</td></tr>';
3013 }
3014
3015 print '</table>';
3016
3017 print '</div>';
3018 print '</div>';
3019 print '<div class="clearboth"></div>';
3020
3021 print dol_get_fiche_end();
3022 }
3023
3024
3025 /*
3026 * Action bar
3027 */
3028 print '<div class="tabsAction">';
3029
3030 $parameters = [];
3031 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3032 if (empty($reshook)) {
3033 if ($action != 'edit') {
3034 if ($user->hasRight('agenda', 'allactions', 'create') ||
3035 (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
3036 print '<div class="inline-block divButAction"><a class="butAction" href="card.php?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Modify").'</a></div>';
3037 } else {
3038 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Modify").'</a></div>';
3039 }
3040
3041 if ($user->hasRight('agenda', 'allactions', 'create') ||
3042 (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
3043 print '<div class="inline-block divButAction"><a class="butAction butActionClone" href="card.php?action=clone&object='.$object->element.'&id='.$object->id.'">'.$langs->trans("ToClone").'</a></div>';
3044 } else {
3045 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("ToClone").'</a></div>';
3046 }
3047
3048 if ($usercandelete) {
3049 print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Delete").'</a></div>';
3050 } else {
3051 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Delete").'</a></div>';
3052 }
3053 }
3054 }
3055
3056 print '</div>';
3057
3058 if ($action != 'edit') {
3059 if (!getDolGlobalString('AGENDA_DISABLE_BUILDDOC')) {
3060 print '<div class="clearboth"></div><div class="fichecenter"><div class="fichehalfleft">';
3061 print '<a name="builddoc"></a>'; // ancre
3062
3063 // Generated documents
3064 $filedir = $conf->agenda->multidir_output[$conf->entity].'/'.$object->id;
3065 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3066
3067 $genallowed = $user->hasRight('agenda', 'myactions', 'read');
3068 $delallowed = $user->hasRight('agenda', 'myactions', 'create');
3069
3070 print $formfile->showdocuments('actions', (string) $object->id, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 0, 0, '', '', '', $langs->getDefaultLang());
3071
3072 if (getDolGlobalString('AGENDA_ENABLE_LINKED_ELEMENTS')) {
3073 // Show links to link elements
3074 $tmparray = $form->showLinkToObjectBlock($object, [], array('myobject'), 1);
3075 if (is_array($tmparray)) {
3076 $linktoelem = $tmparray['linktoelem'];
3077 $htmltoenteralink = $tmparray['htmltoenteralink'];
3078 print $htmltoenteralink;
3079 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
3080 } else {
3081 // backward compatibility
3082 $somethingshown = $form->showLinkedObjectBlock($object, $tmparray);
3083 }
3084 }
3085 print '</div><div class="fichehalfright">';
3086
3087 print '</div></div>';
3088 }
3089 }
3090}
3091
3092// End of page
3093llxFooter();
3094$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
$object ref
Definition info.php:90
Class to manage agenda events (actions)
Class for ActionCommReminder.
Class to manage different types of events.
Class to manage contact/addresses.
Class to manage a WYSIWYG editor.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
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:168
dol_get_first_day_week($day, $month, $year, $gm=false)
Return first day of week for a date.
Definition date.lib.php:679
num_between_day($timestampStart, $timestampEnd, $lastday=0)
Function to return number of days between two dates (date must be UTC date !) Example: 2012-01-01 201...
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:435
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dolGetElementUrl($objectid, $objecttype, $withpicto=0, $option='')
Return link url to an object.
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...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
treeview li table
No Email.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:134
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.