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