dolibarr 24.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
5 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
9 * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
12 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
34// Load Dolibarr environment
35require '../../main.inc.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
45require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
48require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
49require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
50require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
51require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
52require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
53require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
54require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
55require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
56require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
57require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
58
59// Load translation files required by the page
60$langs->loadLangs(["companies", "other", "commercial", "bills", "orders", "agenda", "mails"]);
61
62// Get Parameters
63$action = GETPOST('action', 'aZ09');
64$cancel = GETPOST('cancel', 'alpha');
65$backtopage = GETPOST('backtopage', 'alpha');
66$socpeopleassigned = GETPOST('socpeopleassigned', 'array');
67$origin = GETPOST('origin', 'alpha');
68$originid = GETPOSTINT('originid');
69$confirm = GETPOST('confirm', 'alpha');
70
71$fulldayevent = GETPOST('fullday', 'alpha');
72
73$aphour = GETPOSTINT('aphour');
74$apmin = GETPOSTINT('apmin');
75$p2hour = GETPOSTINT('p2hour');
76$p2min = GETPOSTINT('p2min');
77
78$addreminder = GETPOST('addreminder', 'alpha');
79$offsetvalue = GETPOSTINT('offsetvalue');
80$offsetunit = GETPOST('offsetunittype_duration', 'aZ09');
81$remindertype = GETPOST('selectremindertype', 'aZ09');
82$modelmail = GETPOSTINT('actioncommsendmodel_mail');
83$complete = GETPOST('complete', 'alpha'); // 'na' must be allowed
84$private = GETPOST('private', 'alphanohtml');
85if ($complete == 'na' || $complete == -2) {
86 $complete = -1;
87}
88
89$tzforfullday = null;
90if ($fulldayevent) {
91 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
92 // For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
93 $datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
94 $datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
95 //print $db->idate($datep); exit;
96} else {
97 $datep = dol_mktime($aphour, $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
98 $datef = dol_mktime($p2hour, $p2min, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
99}
100$reg = [];
101if (GETPOST('datep')) {
102 if (GETPOST('datep') == 'now') {
103 $datep = dol_now();
104 } elseif (preg_match('/^([0-9]{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 if an event resource is already in use
1106 if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
1107 $eventDateStart = $object->datep;
1108 $eventDateEnd = $object->datef;
1109
1110 $sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
1111 $sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
1112 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
1113 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
1114 $sql .= " WHERE ac.id <> ".((int) $object->id);
1115 $sql .= " AND er.resource_id IN (";
1116 $sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
1117 $sql .= " WHERE element_id = ".((int) $object->id);
1118 $sql .= " AND element_type = '".$db->escape($object->element)."'";
1119 $sql .= " AND busy = 1";
1120 $sql .= ")";
1121 $sql .= " AND er.busy = 1";
1122 $sql .= " AND (";
1123
1124 // event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
1125 $sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
1126 // event date end between ac.datep and ac.datep2
1127 if (!empty($eventDateEnd)) {
1128 $sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
1129 }
1130 // event date start before ac.datep and event date end after ac.datep2
1131 $sql .= " OR (";
1132 $sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
1133 if (!empty($eventDateEnd)) {
1134 $sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
1135 }
1136 $sql .= ")";
1137
1138 $sql .= ")";
1139 $resql = $db->query($sql);
1140 if (!$resql) {
1141 $error++;
1142 $object->error = $db->lasterror();
1143 $object->errors[] = $object->error;
1144 } else {
1145 if ($db->num_rows($resql) > 0) {
1146 // Resource already in use
1147 $error++;
1148 $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
1149 while ($obj = $db->fetch_object($resql)) {
1150 $object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
1151 }
1152 $object->errors[] = $object->error;
1153 }
1154 $db->free($resql);
1155 }
1156
1157 if ($error) {
1158 setEventMessages($object->error, $object->errors, 'errors');
1159 }
1160 }
1161 }
1162
1163 if (!$error) {
1164 $db->begin();
1165
1166 $result = $object->update($user);
1167
1168 if ($result > 0) {
1169 // Category association
1170 $categories = GETPOST('categories', 'array');
1171 $object->setCategories($categories);
1172
1173 $object->loadReminders($remindertype, 0, false);
1174
1175 // If there is reminders, we remove them
1176 if (!empty($object->reminders)) {
1177 foreach ($object->reminders as $reminder) {
1178 if ($reminder->status < 1) { // If already sent, we never remove it
1179 $reminder->delete($user);
1180 }
1181 }
1182 $object->reminders = [];
1183 }
1184
1185 // Create reminders for every assigned user if reminder is on
1186 if ($addreminder == 'on') {
1187 $actionCommReminder = new ActionCommReminder($db);
1188
1189 $dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
1190
1191 $actionCommReminder->dateremind = $dateremind;
1192 $actionCommReminder->typeremind = $remindertype;
1193 $actionCommReminder->offsetunit = $offsetunit;
1194 $actionCommReminder->offsetvalue = $offsetvalue;
1195 $actionCommReminder->status = $actionCommReminder::STATUS_TODO;
1196 $actionCommReminder->fk_actioncomm = $object->id;
1197 if ($remindertype == 'email') {
1198 $actionCommReminder->fk_email_template = $modelmail;
1199 }
1200
1201 // the notification must be created for every user assigned to the event
1202 foreach ($object->userassigned as $userassigned) {
1203 $actionCommReminder->fk_user = $userassigned['id'];
1204
1205 // We update the event, so we recreate the notification event.
1206 // First we delete all reminders for the user and the type of reminding (all offset dates).
1207 $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
1208 $sqldelete .= " WHERE fk_user = ".((int) $actionCommReminder->fk_user)." AND fk_actioncomm = ".((int) $object->id)." AND typeremind = '".$db->escape($remindertype)."'";
1209 $resqldelete = $db->query($sqldelete);
1210
1211 $res = $actionCommReminder->create($user);
1212
1213 if ($res <= 0) {
1214 // If error
1215 $langs->load("errors");
1216 $error = $langs->trans('ErrorReminderActionCommCreation');
1217 setEventMessages($error, null, 'errors');
1218 $action = 'create';
1219 $donotclearsession = 1;
1220 break;
1221 }
1222 }
1223 }
1224
1225 if (!$error) {
1226 unset($_SESSION[$sessionkeyassignedtouser]);
1227 unset($_SESSION[$sessionkeyassignedtoresource]);
1228
1229 $db->commit();
1230 } else {
1231 $db->rollback();
1232 $action = 'edit';
1233 }
1234 } else {
1235 setEventMessages($object->error, $object->errors, 'errors');
1236 $db->rollback();
1237 }
1238 }
1239 }
1240
1241 if (!$error) {
1242 if (!empty($backtopage)) {
1243 unset($_SESSION[$sessionkeyassignedtouser]);
1244 header("Location: ".$backtopage);
1245 exit;
1246 }
1247 }
1248}
1249
1250// Delete event
1251if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes' && $usercandelete) {
1252 $object->fetch($id);
1253 $object->fetch_optionals();
1254 $object->fetch_userassigned();
1255 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1256
1257 $result = $object->delete($user);
1258
1259 if ($result >= 0) {
1260 header("Location: index.php");
1261 exit;
1262 } else {
1263 setEventMessages($object->error, $object->errors, 'errors');
1264 }
1265}
1266
1267/*
1268 * Action move update, used when user move an event in calendar by drag'n drop
1269 * TODO Move this into page comm/action/index that trigger this call by the drag and drop of event.
1270 */
1271if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate' && $usercancreate) {
1272 $error = 0;
1273
1274 $shour = (int) dol_print_date($object->datep, "%H", 'tzuserrel'); // We take the date visible by user $newdate is also date visible by user.
1275 $smin = (int) dol_print_date($object->datep, "%M", 'tzuserrel');
1276
1277 $newdate = GETPOST('newdate', 'alpha');
1278 if (empty($newdate) || strpos($newdate, 'dayevent_') != 0) {
1279 header("Location: ".$backtopage, true, 307);
1280 exit;
1281 }
1282
1283 $datep = dol_mktime($shour, $smin, 0, (int) substr($newdate, 13, 2), (int) substr($newdate, 15, 2), (int) substr($newdate, 9, 4), 'tzuserrel');
1284 //print dol_print_date($datep, 'dayhour');exit;
1285
1286 if ($datep != $object->datep) {
1287 if (!empty($object->datef)) {
1288 $object->datef += (int) $datep - $object->datep;
1289 }
1290 $object->datep = $datep;
1291
1292 if (!$error) {
1293 // check if an event resource is already in use
1294 if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
1295 $eventDateStart = $object->datep;
1296 $eventDateEnd = $object->datef;
1297
1298 $sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
1299 $sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
1300 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
1301 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
1302 $sql .= " WHERE ac.id <> ".((int) $object->id);
1303 $sql .= " AND er.resource_id IN (";
1304 $sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
1305 $sql .= " WHERE element_id = ".((int) $object->id);
1306 $sql .= " AND element_type = '".$db->escape($object->element)."'";
1307 $sql .= " AND busy = 1";
1308 $sql .= ")";
1309 $sql .= " AND er.busy = 1";
1310 $sql .= " AND (";
1311
1312 // event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
1313 $sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
1314 // event date end between ac.datep and ac.datep2
1315 if (!empty($eventDateEnd)) {
1316 $sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
1317 }
1318 // event date start before ac.datep and event date end after ac.datep2
1319 $sql .= " OR (";
1320 $sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
1321 if (!empty($eventDateEnd)) {
1322 $sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
1323 }
1324 $sql .= ")";
1325
1326 $sql .= ")";
1327 $resql = $db->query($sql);
1328 if (!$resql) {
1329 $error++;
1330 $object->error = $db->lasterror();
1331 $object->errors[] = $object->error;
1332 } else {
1333 if ($db->num_rows($resql) > 0) {
1334 // Resource already in use
1335 $error++;
1336 $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
1337 while ($obj = $db->fetch_object($resql)) {
1338 $object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
1339 }
1340 $object->errors[] = $object->error;
1341 }
1342 $db->free($resql);
1343 }
1344
1345 if ($error) {
1346 setEventMessages($object->error, $object->errors, 'errors');
1347 }
1348 }
1349 }
1350
1351 if (!$error) {
1352 $db->begin();
1353 $result = $object->update($user);
1354 if ($result < 0) {
1355 $error++;
1356 setEventMessages($object->error, $object->errors, 'errors');
1357 $db->rollback();
1358 } else {
1359 $db->commit();
1360 }
1361 }
1362 }
1363 if (!empty($backtopage)) {
1364 header("Location: ".$backtopage, true, 307);
1365 exit;
1366 } else {
1367 $action = '';
1368 }
1369}
1370
1371// Actions to delete doc
1372$upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref);
1373$permissiontoadd = ($user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'read')));
1374if (empty($reshook)) {
1375 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1376}
1377
1378
1379/*
1380 * View
1381 */
1382
1383$form = new Form($db);
1384$formproject = new FormProjets($db);
1385
1386$arrayrecurrulefreq = array(
1387 'no' => $langs->trans("OnceOnly"),
1388 'YEARLY' => $langs->trans("EveryYear"),
1389 'MONTHLY' => $langs->trans("EveryMonth"),
1390 'WEEKLY' => $langs->trans("EveryWeek")
1391 // 'DAILY'=>$langs->trans("EveryDay")
1392);
1393
1394
1395$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda|DE:Modul_Terminplanung';
1396llxHeader('', $langs->trans("Agenda"), $help_url);
1397
1398if ($action == 'create') {
1399 $contact = new Contact($db);
1400
1401 $socpeopleassigned = GETPOST("socpeopleassigned", 'array');
1402 if (!empty($socpeopleassigned[0])) {
1403 $result = $contact->fetch($socpeopleassigned[0]);
1404 if ($result < 0) {
1405 dol_print_error($db, $contact->error);
1406 }
1407 }
1408
1409 dol_set_focus("#label");
1410
1411 if (!empty($conf->use_javascript_ajax)) {
1412 print "\n".'<script type="text/javascript">';
1413 print '$(document).ready(function () {
1414 function setdatefields()
1415 {
1416 if ($("#fullday:checked").val() == null) {
1417 $(".fulldaystarthour").removeAttr("disabled");
1418 $(".fulldaystartmin").removeAttr("disabled");
1419 $(".fulldayendhour").removeAttr("disabled");
1420 $(".fulldayendmin").removeAttr("disabled");
1421 $("#p2").removeAttr("disabled");
1422 } else {
1423 $(".fulldaystarthour").prop("disabled", true).val("00");
1424 $(".fulldaystartmin").prop("disabled", true).val("00");
1425 $(".fulldayendhour").prop("disabled", true).val("23");
1426 $(".fulldayendmin").prop("disabled", true).val("59");
1427 $("#p2").removeAttr("disabled");
1428 }
1429 }
1430 $("#fullday").change(function() {
1431 console.log("setdatefields");
1432 setdatefields();
1433 });
1434 var old_startdate = null;
1435 $("#ap").focus(function() {
1436 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1437 });
1438 $("#ap").next(".ui-datepicker-trigger").click(function() {
1439 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1440 });
1441 $("#ap").change(function() {
1442 setTimeout(function() {
1443 if ($("#p2").val() !== "") {
1444 var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
1445 var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
1446 if (new_startdate > old_enddate) {
1447 var timeDiff = old_enddate - old_startdate;
1448 var new_enddate = new Date(new_startdate.getTime() + timeDiff);
1449 $("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
1450 $("#p2day").val(new_enddate.getDate());
1451 $("#p2month").val(new_enddate.getMonth() + 1);
1452 $("#p2year").val(new_enddate.getFullYear());
1453 }
1454 }
1455 }, 0);
1456 });
1457 $("#actioncode").change(function() {
1458 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
1459 else $("#dateend").removeClass("fieldrequired");
1460 });
1461 $("#aphour,#apmin").change(function() {
1462 if ($("#actioncode").val() == \'AC_RDV\') {
1463 var oldhour = parseInt($("#aphour").val());
1464 var oldmin = parseInt($("#apmin").val());
1465 var oldday = parseInt($("#apday").val());
1466 var oldmonth = $("#apmonth").val();
1467 var oldyear = $("#apyear").val();
1468
1469 var newhour = oldhour + 1;
1470 var newday = oldday;
1471 var newmonth = oldmonth;
1472 var newyear = oldyear;
1473 if (newhour >= 24) {
1474 newhour = 0;
1475 newday = oldday + 1;
1476 }
1477 console.log("Start date was changed, we modify end date "+oldhour+" "+oldmin+" -> "+newhour+" "+oldmin);
1478 $("#p2hour").val(("00" + newhour).substr(-2,2));
1479 $("#p2min").val(("00" + oldmin).substr(-2,2));
1480 $("#p2day").val(newday);
1481 $("#p2month").val(newmonth);
1482 $("#p2year").val(newyear);
1483 $("#p2").val($("#ap").val());
1484 }
1485 });
1486 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
1487 else $("#dateend").removeClass("fieldrequired");
1488 setdatefields();
1489 })';
1490 print '</script>'."\n";
1491 }
1492
1493 print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
1494 print '<input type="hidden" name="token" value="'.newToken().'">';
1495 print '<input type="hidden" name="action" value="add">';
1496 print '<input type="hidden" name="donotclearsession" value="1">';
1497 print '<input type="hidden" name="page_y" value="">';
1498 if ($backtopage) {
1499 print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
1500 }
1501 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1502 print '<input type="hidden" name="actioncode" value="'.dol_getIdFromCode($db, 'AC_OTH', 'c_actioncomm').'">';
1503 }
1504
1505 print load_fiche_titre($langs->trans("AddAnAction"), '', 'title_agenda');
1506
1507 print dol_get_fiche_head();
1508
1509 print '<div class="divcreate">';
1510 print '<table class="border centpercent nobottom">';
1511
1512 // Title
1513 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>';
1514
1515 // Type of event
1516 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1517 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Type").'</span></b></td><td>';
1518 $default = getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT', 'AC_OTH');
1519 if (empty($default)) {
1520 $default = 'AC_OTH';
1521 }
1522 print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
1523 $selectedvalue = GETPOSTISSET("actioncode") ? GETPOST("actioncode", 'aZ09') : ($object->type_code ? $object->type_code : $default);
1524 print $formactions->select_type_actions($selectedvalue, "actioncode", "systemauto", 0, -1, 0, 1); // TODO Replace 0 with -2 in onlyautoornot
1525 print '</td></tr>';
1526 }
1527
1528 // Full day
1529 print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td>';
1530 print '<td class="valignmiddle height30">';
1531 print '<div>';
1532 print '<input class="valignmiddle" type="checkbox" id="fullday" name="fullday" '.(GETPOST('fullday') ? ' checked' : '').'><label for="fullday" class="valignmiddle small">'.$langs->trans("EventOnFullDay").'</label>';
1533 print '</div>';
1534 print '</td></tr>';
1535
1536 $datep = ($datep ? $datep : (is_null($object->datep) ? '' : $object->datep));
1537 if (GETPOST('datep', 'alpha', 1)) {
1538 $datep = dol_stringtotime(GETPOST('datep', 'alpha', 1), 'tzuserrel');
1539 }
1540 $datef = ($datef ? $datef : $object->datef);
1541 if (GETPOST('datef', 'alpha', 1)) {
1542 $datef = dol_stringtotime(GETPOST('datef', 'alpha', 1), 'tzuserrel');
1543 }
1544 if (empty($datef) && !empty($datep)) {
1545 if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || (!getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') || getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') == '-1')) {
1546 $datef = dol_time_plus_duree($datep, getDolGlobalInt('AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS', 1), 'h');
1547 }
1548 }
1549
1550 // Date start
1551 print '<tr><td class="nowrap">';
1552 print '</td><td>';
1553 print '<div class="inline-block">';
1554 if (GETPOST("afaire") == 1) {
1555 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"
1556 } else {
1557 print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel');
1558 }
1559 print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span><br class="showonsmartphone"> ';
1560 print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel');
1561 print '</div>';
1562
1563 //print '</td></tr>';
1564
1565 // Recurring event
1566 $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
1567 if ($userepeatevent) {
1568 //print '<tr><td></td><td>';
1569 print '<div class="clearbothonsmartphone hideonsmartphone inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>';
1570
1571 // Repeat
1572 print '<div class="inline-block small" data-html="repeat">';
1573 print '<span class="opacitymedium">';
1574 print img_picto($langs->trans("Recurrence"), 'recurring', 'style="margin-left: 3px" class="paddingright"');
1575 print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
1576
1577 $selectedrecurrulefreq = 'no';
1578 $selectedrecurrulebyyearmonthday = '';
1579 $selectedrecurrulebymonthday = '';
1580 $selectedrecurrulebyday = '';
1581 $object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
1582 $object->recurrule .= GETPOSTISSET('BYYEARMONTHDAY') ? "_BYYEARMONTHDAY".GETPOST('BYYEARMONTHDAY', 'alpha') : "";
1583 $object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
1584 $object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
1585
1586
1587 $reg = [];
1588 if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
1589 $selectedrecurrulefreq = $reg[1];
1590 }
1591 if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
1592 $selectedrecurrulebyyearmonthday = (int) $reg[1];
1593 }
1594 if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
1595 $selectedrecurrulebymonthday = (int) $reg[1];
1596 }
1597 if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
1598 $selectedrecurrulebyday = (int) $reg[1];
1599 }
1600
1601 print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly minwidth125 maxwidth150');
1602 print '</span>';
1603 // print '<script>console.log("recurrule: " +'.$object->recurrule.')</script>';
1604 // For recursive event
1605
1606
1607 // If recurrulefreq is MONTHLY
1608 /*
1609 print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
1610 print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
1611 print '</div>';
1612 // If recurrulefreq is WEEKLY
1613 print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
1614 print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
1615 print '</div>';
1616 */
1617
1618 // limit date
1619 $repeateventlimitdate = empty($repeateventlimitdate) ? (dol_now() + ((24 * 3600 * 365) + 1)) : $repeateventlimitdate;
1620
1621 print '<div class="hidden marginrightonly inline-block repeateventlimitdate">';
1622 print $langs->trans("Until")." ";
1623 print $form->selectDate($repeateventlimitdate, 'limit', 0, 0, 0, "action", 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
1624 print '</div>';
1625 ?>
1626 <script type="text/javascript">
1627 jQuery(document).ready(function() {
1628 function init_repeat() {
1629 console.log("recurrule: " + "<?php echo $object->recurrule; ?>");
1630 console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>");
1631 console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>");
1632 console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>");
1633 console.log("reg4: " + "<?php echo $selectedrecurrulebyyearmonthday; ?>");
1634 console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>");
1635 if (jQuery("#recurrulefreq").val() == 'YEARLY') {
1636 /* jQuery(".repeateventBYYEARMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1637 jQuery(".repeateventlimitdate").css("display", "inline-block");
1638 jQuery(".repeateventBYMONTHDAY").hide();
1639 jQuery(".repeateventBYDAY").hide();
1640 } else if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
1641 /* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1642 jQuery(".repeateventlimitdate").css("display", "inline-block");
1643 jQuery(".repeateventBYYEARMONTHDAY").hide();
1644 jQuery(".repeateventBYDAY").hide();
1645 } else if (jQuery("#recurrulefreq").val() == 'WEEKLY') {
1646 jQuery(".repeateventBYYEARMONTHDAY").hide();
1647 jQuery(".repeateventBYMONTHDAY").hide();
1648 /* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
1649 jQuery(".repeateventlimitdate").css("display", "inline-block");
1650 } else {
1651 jQuery(".repeateventBYYEARMONTHDAY").hide();
1652 jQuery(".repeateventBYMONTHDAY").hide();
1653 jQuery(".repeateventBYDAY").hide();
1654 jQuery(".repeateventlimitdate").hide();
1655 }
1656 }
1657 init_repeat();
1658 jQuery("#recurrulefreq").change(function() {
1659 init_repeat();
1660 });
1661 });
1662 </script>
1663 <?php
1664 print '</div>';
1665 // print '</td></tr>';
1666 }
1667
1668 print '</td></tr>';
1669
1670
1671 // Location
1672 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
1673 print '<tr><td class="titlefieldcreate">'.$langs->trans("Location").'</td><td>';
1674 print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
1675 print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.(GETPOST('location') ? GETPOST('location') : $object->location).'"></td></tr>';
1676 }
1677
1678 print '</table>';
1679 print '</div>';
1680
1681 print '<br>';
1682
1683 print '<div class="divcreate">';
1684 print '<table class="border centpercent nobottom">';
1685
1686 // Assigned to user
1687 print '<tr><td class="nowrap titlefieldcreate"><span>';
1688 print $langs->trans("AssignedTo");
1689 print '</span></td><td>';
1690 $listofuserid = [];
1691 $listofcontactid = [];
1692 $listofotherid = [];
1693
1694 if (empty($donotclearsession)) {
1695 $assignedtouser = GETPOST("assignedtouser") ? GETPOST("assignedtouser") : (!empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : $user->id);
1696 if ($assignedtouser) {
1697 $listofuserid[$assignedtouser] = array('id' => $assignedtouser, 'mandatory' => 0); // Owner first
1698 }
1699 //$listofuserid[$user->id] = array('id'=>$user->id, 'mandatory'=>0, 'transparency'=>(GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1)); // 1 by default at first init
1700 $listofuserid[$assignedtouser]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1); // 1 by default at first init
1701 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
1702 } else {
1703 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
1704 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
1705 }
1706 if (!is_array($listofuserid)) {
1707 $listofuserid = [];
1708 }
1709 $firstelem = reset($listofuserid);
1710 if (isset($listofuserid[$firstelem['id']])) {
1711 $listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
1712 }
1713 }
1714 print '<!-- list of user to assign -->'."\n";
1715 print '<div class="assignedtouser">';
1716 print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid);
1717 print '</div>';
1718 print '</td></tr>';
1719
1720 if (isModEnabled('resource')) {
1721 // Resources
1722 print '<tr><td class="tdtop nowrap">'.$langs->trans("Resource").'</td><td>';
1723
1724 $listofresourceid = [];
1725 if (empty($donotclearsession)) {
1726 $assignedtoresource = GETPOST("assignedtoresource");
1727 if ($assignedtoresource) {
1728 $listofresourceid[$assignedtoresource] = array('id' => $assignedtoresource, 'mandatory' => 0); // Owner first
1729 }
1730 $_SESSION[$sessionkeyassignedtoresource] = json_encode($listofresourceid);
1731 } else {
1732 if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
1733 $listofresourceid = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
1734 }
1735 if (!is_array($listofresourceid)) {
1736 $listofresourceid = [];
1737 }
1738 $firstelem = reset($listofresourceid);
1739 if ($firstelem && isset($listofresourceid[$firstelem['id']])) {
1740 $listofresourceid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
1741 }
1742 }
1743 print '<div class="assignedtoresource">';
1744 print $form->select_dolresources_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtoresource', 1, [], 0, '', [], '0', 0, 0, 'AND u.statut != 0', 1, $listofresourceid);
1745 print '</div>';
1746 print '</td></tr>';
1747 }
1748
1749 if (isModEnabled('category')) {
1750 // Categories
1751 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1752 print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
1753 print "</td></tr>";
1754 }
1755
1756 print '</table>';
1757 print '</div>';
1758
1759
1760 print '<br>';
1761
1762 print '<div class="divcreate">';
1763 print '<table class="border centpercent nobottom">';
1764
1765 // Status
1766 print '<tr><td>'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td>';
1767 print '<td>';
1768 $percent = $complete !== '' ? $complete : -1;
1769 if (GETPOSTISSET('status')) {
1770 $percent = GETPOST('status');
1771 } elseif (GETPOSTISSET('percentage')) {
1772 $percent = GETPOSTINT('percentage');
1773 } else {
1774 if ($complete == '0' || GETPOST("afaire") == 1) {
1775 $percent = '0';
1776 } elseif ($complete == 100 || GETPOST("afaire") == 2) {
1777 $percent = 100;
1778 }
1779 }
1780 print $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300', 1);
1781 print '</td></tr>';
1782
1783 if (isModEnabled("societe")) {
1784 // Related company
1785 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ActionOnCompany").'</td><td>';
1786 if (GETPOSTINT('socid') > 0) {
1787 $societe = new Societe($db);
1788 $societe->fetch(GETPOSTINT('socid'));
1789 print $societe->getNomUrl(1);
1790 print '<input type="hidden" id="socid" name="socid" value="'.GETPOSTINT('socid').'">';
1791 } else {
1792 $events = [];
1793 $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
1794 //For external user force the company to user company
1795 if (!empty($user->socid)) {
1796 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($user->socid, 'socid', '', 1, 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1797 } else {
1798 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '', $langs->trans('SelectThirdParty'), 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1799 }
1800 }
1801 print '</td></tr>';
1802
1803 // Related contact
1804 print '<tr><td class="nowrap">'.$langs->trans("ActionOnContact").'</td><td>';
1805 $preselectedids = GETPOST('socpeopleassigned', 'array:int');
1806 if (GETPOSTINT('contactid')) {
1807 $preselectedids[GETPOSTINT('contactid')] = GETPOSTINT('contactid');
1808 }
1809 if ($origin == 'contact') {
1810 $preselectedids[GETPOSTINT('originid')] = GETPOSTINT('originid');
1811 }
1812 // select "all" or "none" contact by default
1813 if (getDolGlobalInt('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT')) {
1814 // Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
1815 $select_contact_default = 0; // select "all" contacts by default : avoid to use it if there is a lot of contacts
1816 } else {
1817 $select_contact_default = -1; // select "none" by default
1818 }
1819 print img_picto('', 'contact', 'class="pictofixedwidth"');
1820
1821 if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
1822 // FIXME Use a select without the "multiple" (not supported when CONTACT_USE_SEARCH_TO_SELECT is on) or allow use only when $object->socid is set...
1823 /*
1824 $selected = array_keys($object->socpeopleassigned);
1825 print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
1826 */
1827 $sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
1828 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
1829 print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
1830 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
1831 } else {
1832 print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
1833 }
1834
1835 print '</td></tr>';
1836 }
1837
1838 // Project
1839 if (isModEnabled('project')) {
1840 $langs->load("projects");
1841
1842 $projectid = GETPOSTINT('projectid');
1843
1844 print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td id="project-input-container">';
1845 print img_picto('', 'project', 'class="pictofixedwidth"');
1846 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');
1847
1848 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').'">';
1849 print '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>';
1850 $urloption = '?action=create&donotclearsession=1';
1851 $url = dol_buildpath('comm/action/card.php', 2).$urloption;
1852
1853 // update task list
1854 ?>
1855 <script type="text/javascript">
1856 $(document).ready(function () {
1857 $("#projectid").change(function () {
1858 var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
1859 console.log("Call url to get the new list of tasks: "+url);
1860 $.get(url, function(data) {
1861 console.log(data);
1862 if (data) $("#taskid").html(data).select2();
1863 })
1864 });
1865 });
1866 </script>
1867 <?php
1868
1869 print '</td></tr>';
1870
1871 // Task
1872 print '<tr><td class="titlefieldcreate">'.$langs->trans("Task").'</td><td id="project-task-input-container" >';
1873 print img_picto('', 'projecttask', 'class="pictofixedwidth"');
1874 $projectsListId = '';
1875 if (!empty($projectid)) {
1876 $projectsListId = $projectid;
1877 }
1878
1879 $tid = GETPOSTISSET("projecttaskid") ? GETPOSTINT("projecttaskid") : (GETPOSTISSET("taskid") ? GETPOSTINT("taskid") : '');
1880
1881 if (empty($projectsListId)) {
1882 print '<select class="valignmiddle flat maxwidth500 widthcentpercentminusxx minwidth150imp" id="taskid" name="taskid">';
1883 print '<option class="opacitymedium">&nbsp;</option>';
1884 print '<option class="opacitymedium" disabled data-html="'.dolPrintHTMLForAttribute($langs->trans("SelectAProjectFirst")).'">'.$langs->trans("SelectAProjectFirst").'</option>';
1885 print '</select>';
1886 print ajax_combobox('taskid');
1887 } else {
1888 print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
1889 }
1890 print '</td></tr>';
1891 }
1892
1893 // Object linked
1894 if (!empty($origin) && !empty($originid)) {
1895 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1896
1897 $hasPermissionOnLinkedObject = 0;
1898
1899 $elProp = getElementProperties($origin);
1900 $modulecodetouseforpermissioncheck = $elProp['module'];
1901 // Keep permission check aligned with rights class aliases (see restrictedArea()).
1902 $submodulecodetouseforpermissioncheck = $elProp['subelement'];
1903
1904 switch ($modulecodetouseforpermissioncheck) {
1905 case 'productbatch':
1906 $modulecodetouseforpermissioncheck = 'produit';
1907 break;
1908 case 'eventorganization':
1909 // Event organization relies on Project permissions
1910 $modulecodetouseforpermissioncheck = 'projet';
1911 $submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
1912 break;
1913 default:
1914 // No mapping needed, keep original values
1915 break;
1916 }
1917
1918 if ($user->hasRight($modulecodetouseforpermissioncheck, 'read') || $user->hasRight($modulecodetouseforpermissioncheck, $elProp['element'], 'read')) {
1919 $hasPermissionOnLinkedObject = 1;
1920 }
1921 //var_dump('origin='.$origin.' originid='.$originid.' hasPermissionOnLinkedObject='.$hasPermissionOnLinkedObject);
1922
1923 if (! in_array($origin, array('societe', 'project', 'project_task', 'user'))) {
1924 // We do not use link for object that already contains a hard coded field to make links with agenda events
1925 print '<tr><td class="titlefieldcreate">'.$langs->trans("LinkedObject").'</td>';
1926 print '<td colspan="3">';
1927 if ($hasPermissionOnLinkedObject) {
1928 print dolGetElementUrl($originid, $origin, 1);
1929 print '<input type="hidden" name="fk_element" value="'.$originid.'">';
1930 print '<input type="hidden" name="elementtype" value="'.$origin.'">';
1931 print '<input type="hidden" name="originid" value="'.$originid.'">';
1932 print '<input type="hidden" name="origin" value="'.$origin.'">';
1933 } else {
1934 print '<!-- no permission on object to link '.$origin.' id '.$originid.' -->';
1935 }
1936 print '</td></tr>';
1937 }
1938 }
1939
1940 // Priority
1941 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
1942 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td colspan="3">';
1943 print '<input type="text" name="priority" value="'.(GETPOSTISSET('priority') ? GETPOSTINT('priority') : ($object->priority ? $object->priority : '')).'" size="5">';
1944 print '</td></tr>';
1945 }
1946
1947 // Description
1948 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
1949 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1950 $doleditor = new DolEditor('note', (GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : $object->note_private), '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
1951 $doleditor->Create();
1952 print '</td></tr>';
1953
1954 // Other attributes
1955 $parameters = [];
1956 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1957 print $hookmanager->resPrint;
1958 if (empty($reshook)) {
1959 print $object->showOptionals($extrafields, 'create', $parameters);
1960 }
1961
1962 print '</table>';
1963 print '</div>';
1964
1965 if ($enablereminders) {
1966 //checkbox create reminder
1967 print '<hr>';
1968
1969 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>';
1970
1971 print '<div class="reminderparameters" '.(empty(GETPOST('addreminder')) ? 'style="display: none;' : '').' ">';
1972 print '<br>';
1973
1974 print '<table class="border centpercent">';
1975
1976 //Reminder
1977 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
1978 print '<input class="width50" type="number" name="offsetvalue" value="'.(GETPOSTISSET('offsetvalue') ? GETPOSTINT('offsetvalue') : getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30)).'"> ';
1979
1980 print $form->selectTypeDuration('offsetunit', (empty($offsetunit) ? 'i' : $offsetunit), $TDurationTypesExcluded);
1981 print '</td></tr>';
1982
1983 //Reminder Type
1984 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
1985 print $form->selectarray('selectremindertype', $TRemindTypes, '', 0, 0, 0, '', 0, 0, 0, '', 'minwidth200 maxwidth500', 1);
1986 print '</td></tr>';
1987
1988 //Mail Model
1989 if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
1990 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
1991 print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (empty($modelmail) ? 0 : $modelmail));
1992 print '</td></tr>';
1993 }
1994
1995 print '</table>';
1996 print '</div>';
1997
1998 $reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
1999 $reminderDefaultOffset = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
2000 $reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
2001 $reminderDefaultEmailModel = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
2002
2003 print "\n".'<script type="text/javascript">';
2004 print '$(document).ready(function () {
2005 const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
2006 $("#actioncode").change(function(){
2007 var selected_event_type = $("#actioncode option:selected").val();
2008
2009 if (reminderDefaultEventTypes.includes(selected_event_type)) {
2010 $(".reminderparameters").show();
2011 $("#addreminder").prop("checked", true);
2012
2013 // Set period with default reminder period
2014 $("[name=\"offsetvalue\"]").val(\'' . dol_escape_js((string) $reminderDefaultOffset) . '\');
2015 $("#select_offsetunittype_duration").select2("destroy");
2016 $("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
2017 $("#select_offsetunittype_duration").select2();
2018
2019 $("#selectremindertype").select2("destroy");
2020 $("#selectremindertype").val("email");
2021 $("#selectremindertype").select2();
2022
2023 // Set default reminder mail model
2024 $("#select_actioncommsendmodel_mail").closest("tr").show();
2025 $("#select_actioncommsendmodel_mail").select2("destroy");
2026 $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js((string) $reminderDefaultEmailModel).'\');
2027 $("#select_actioncommsendmodel_mail").select2();
2028 }
2029 });
2030 })';
2031 print '</script>'."\n";
2032
2033 print "\n".'<script type="text/javascript">';
2034 print '$(document).ready(function () {
2035 function toggle_reminder_part(evt) {
2036 console.log("Toggle reminder part");
2037 if ($("#addreminder").is(":checked")) {
2038 $(".reminderparameters").show();
2039 } else {
2040 $(".reminderparameters").hide();
2041 }
2042 $("#selectremindertype").select2("destroy");
2043 $("#selectremindertype").select2();
2044 $("#select_offsetunittype_duration").select2("destroy");
2045 $("#select_offsetunittype_duration").select2();
2046 selectremindertype();
2047 }
2048
2049 toggle_reminder_part();
2050 $("#addreminder").click(toggle_reminder_part);
2051
2052 $("#selectremindertype").change(function(){
2053 selectremindertype();
2054 });
2055
2056 function selectremindertype() {
2057 console.log("Call selectremindertype");
2058 var selected_option = $("#selectremindertype option:selected").val();
2059 if(selected_option == "email") {
2060 $("#select_actioncommsendmodel_mail").closest("tr").show();
2061 } else {
2062 $("#select_actioncommsendmodel_mail").closest("tr").hide();
2063 }
2064 }
2065
2066 })';
2067 print '</script>'."\n";
2068 }
2069
2070 print dol_get_fiche_end();
2071
2072 print $form->buttonsSaveCancel("Create");
2073
2074 print "</form>";
2075}
2076
2077// View or edit
2078if ($id > 0 && $action != 'create') {
2079 $result1 = $object->fetch($id);
2080 if ($result1 <= 0) {
2081 recordNotFound('', 0);
2082 }
2083
2084 $result2 = $object->fetch_thirdparty();
2085 $result2 = $object->fetchProject();
2086 $result3 = $object->fetch_contact();
2087 $result4 = $object->fetch_userassigned();
2088 $result5 = $object->fetch_optionals();
2089
2090 if ($listUserAssignedUpdated || $donotclearsession) {
2091 $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
2092
2093 $datep = dol_mktime($fulldayevent ? 0 : $aphour, $fulldayevent ? 0 : $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
2094 $datef = dol_mktime($fulldayevent ? 23 : $p2hour, $fulldayevent ? 59 : $p2min, $fulldayevent ? 59 : 0, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
2095
2096 $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm');
2097 $object->label = GETPOST("label", "alphanohtml");
2098 $object->datep = $datep;
2099 $object->datef = $datef;
2100 $object->percentage = $percentage;
2101 $object->priority = GETPOSTINT("priority");
2102 $object->fulldayevent = GETPOST("fullday") ? 1 : 0;
2103 $object->location = GETPOST('location', "alphanohtml");
2104 $object->socid = GETPOSTINT("socid");
2105 $socpeopleassigned = GETPOST("socpeopleassigned", 'array');
2106 foreach ($socpeopleassigned as $tmpid) {
2107 $object->socpeopleassigned[$id] = array('id' => $tmpid);
2108 }
2109 $object->contact_id = GETPOSTINT("contactid");
2110 $object->fk_project = GETPOSTINT("projectid");
2111
2112 $object->note_private = GETPOST("note", 'restricthtml');
2113 }
2114
2115 if ($result2 < 0 || $result3 < 0 || $result4 < 0 || $result5 < 0) {
2116 dol_print_error($db, $object->error);
2117 exit;
2118 }
2119
2120
2121 /*
2122 * Show tabs
2123 */
2124
2125 $head = actions_prepare_head($object);
2126
2127 $now = dol_now();
2128 $delay_warning = getDolGlobalInt('MAIN_DELAY_ACTIONS_TODO') * 24 * 60 * 60;
2129
2130
2131 // Deletion confirmation action
2132 if ($action == 'delete') {
2133 print $form->formconfirm("card.php?id=".urlencode((string) ($id)), $langs->trans("DeleteAction"), $langs->trans("ConfirmDeleteAction"), "confirm_delete", '', '', 1);
2134 }
2135
2136 if ($action == 'edit') {
2137 $caneditdateorowner = ($object->type != 'systemauto');
2138
2139 if (!empty($conf->use_javascript_ajax)) {
2140 print "\n".'<script type="text/javascript">';
2141 print '$(document).ready(function () {
2142 function setdatefields()
2143 {
2144 if ($("#fullday:checked").val() == null) {
2145 $(".fulldaystarthour").removeAttr("disabled");
2146 $(".fulldaystartmin").removeAttr("disabled");
2147 $(".fulldayendhour").removeAttr("disabled");
2148 $(".fulldayendmin").removeAttr("disabled");
2149 } else {
2150 $(".fulldaystarthour").prop("disabled", true).val("00");
2151 $(".fulldaystartmin").prop("disabled", true).val("00");
2152 $(".fulldayendhour").prop("disabled", true).val("23");
2153 $(".fulldayendmin").prop("disabled", true).val("59");
2154 }
2155 }
2156
2157 '.($caneditdateorowner ? ' setdatefields();' : '').'
2158
2159 $("#fullday").change(function() {
2160 setdatefields();
2161 });
2162 var old_startdate = null;
2163 $("#ap").focus(function() {
2164 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2165 });
2166 $("#ap").next(".ui-datepicker-trigger").click(function() {
2167 old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2168 });
2169 $("#ap").change(function() {
2170 setTimeout(function() {
2171 if ($("#p2").val() !== "") {
2172 var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
2173 var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
2174 if (new_startdate > old_enddate) {
2175 var timeDiff = old_enddate - old_startdate;
2176 var new_enddate = new Date(new_startdate.getTime() + timeDiff);
2177 $("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
2178 $("#p2day").val(new_enddate.getDate());
2179 $("#p2month").val(new_enddate.getMonth() + 1);
2180 $("#p2year").val(new_enddate.getFullYear());
2181 }
2182 }
2183 }, 0);
2184 });
2185 $("#actioncode").change(function() {
2186 if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
2187 else $("#dateend").removeClass("fieldrequired");
2188 });
2189 })';
2190 print '</script>'."\n";
2191 }
2192
2193 print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
2194 print '<input type="hidden" name="token" value="'.newToken().'">';
2195 print '<input type="hidden" name="action" value="update">';
2196 print '<input type="hidden" name="id" value="'.$id.'">';
2197 print '<input type="hidden" name="ref_ext" value="'.$object->ref_ext.'">';
2198 print '<input type="hidden" name="page_y" value="">';
2199 if ($backtopage) {
2200 print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
2201 }
2202 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE') && ! preg_match('/^TICKET_MSG_PRIVATE/', $object->code)) {
2203 print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
2204 }
2205
2206 print dol_get_fiche_head($head, 'card', $langs->trans("Action"), 0, 'action');
2207
2208 print '<table class="border tableforfield centpercent">';
2209
2210 // Ref
2211 print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>'.$object->id.'</td></tr>';
2212
2213 // Title
2214 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>';
2215
2216 // Type of event
2217 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && $object->elementtype != "ticket") {
2218 print '<tr><td class="fieldrequired">'.$langs->trans("Type").'</td><td>';
2219 if ($object->type_code != 'AC_OTH_AUTO') {
2220 print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
2221 print $formactions->select_type_actions(GETPOST("actioncode", 'aZ09') ? GETPOST("actioncode", 'aZ09') : $object->type_code, "actioncode", "systemauto", 0, 0, 0, 1);
2222 } else {
2223 print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
2224 print $object->getTypePicto();
2225 print $langs->trans("Action".$object->type_code);
2226 }
2227 print '</td></tr>';
2228 }
2229
2230 // Private
2231 if ($object->elementtype == 'ticket') {
2232 print '<tr><td>'.$langs->trans("MarkMessageAsPrivate");
2233 print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
2234 print '</td><td><input type="checkbox" id="private" name="private" '.(preg_match('/^TICKET_MSG_PRIVATE/', $object->code) ? ' checked' : '').'></td></tr>';
2235 }
2236
2237 // Full day event
2238 print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td class="valignmiddle height30 small">';
2239 print '<input '.($caneditdateorowner ? '' : ' disabled').' type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
2240 print '<label for="fullday">'.$langs->trans("EventOnFullDay").'</label>';
2241
2242 // // Recurring event
2243 // $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
2244 // if ($userepeatevent) {
2245 // // Repeat
2246 // //print '<tr><td></td><td colspan="3">';
2247 // print ' &nbsp; &nbsp; &nbsp; &nbsp; <div class="opacitymedium inline-block">';
2248 // print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
2249 // print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
2250 // $selectedrecurrulefreq = 'no';
2251 // $selectedrecurrulebymonthday = '';
2252 // $selectedrecurrulebyday = '';
2253 // if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
2254 // $selectedrecurrulefreq = $reg[1];
2255 // }
2256 // if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
2257 // $selectedrecurrulebymonthday = $reg[1];
2258 // }
2259 // if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
2260 // $selectedrecurrulebyday = $reg[1];
2261 // }
2262 // print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
2263 // // If recurrulefreq is MONTHLY
2264 // print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
2265 // print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
2266 // print '</div>';
2267 // // If recurrulefreq is WEEKLY
2268 // print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
2269 // print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
2270 // print '</div>';
2271 // print '<script type="text/javascript">
2272 // jQuery(document).ready(function() {
2273 // function init_repeat()
2274 // {
2275 // if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
2276 // {
2277 // jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
2278 // jQuery(".repeateventBYDAY").hide();
2279 // }
2280 // else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
2281 // {
2282 // jQuery(".repeateventBYMONTHDAY").hide();
2283 // jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
2284 // }
2285 // else
2286 // {
2287 // jQuery(".repeateventBYMONTHDAY").hide();
2288 // jQuery(".repeateventBYDAY").hide();
2289 // }
2290 // }
2291 // init_repeat();
2292 // jQuery("#recurrulefreq").change(function() {
2293 // init_repeat();
2294 // });
2295 // });
2296 // </script>';
2297 // print '</div>';
2298 // //print '</td></tr>';
2299 // }
2300 print '</td></tr>';
2301
2302 // Date start - end
2303 print '<tr><td class="nowrap">';
2304 print '</td><td>';
2305 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2306 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');
2307 print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span> ';
2308 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');
2309 print '</td></tr>';
2310
2311 // Location
2312 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2313 print '<tr><td>'.$langs->trans("Location").'</td><td>';
2314 print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
2315 print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.$object->location.'"></td></tr>';
2316 }
2317
2318 print '<tr class="tdsmallheight"><td class="tdsmallheight">&nbsp;</td><td class="tdsmallheight"></td></tr>';
2319
2320 // Assigned to
2321 $listofuserid = []; // User assigned
2322 if (empty($donotclearsession)) {
2323 if ($object->userownerid > 0) {
2324 $listofuserid[$object->userownerid] = array(
2325 'id' => $object->userownerid,
2326 'type' => 'user',
2327 //'transparency'=>$object->userassigned[$user->id]['transparency'],
2328 'transparency' => $object->transparency, // Force transparency on ownerfrom event
2329 'answer_status' => (isset($object->userassigned[$object->userownerid]['answer_status']) ? $object->userassigned[$object->userownerid]['answer_status'] : null),
2330 'mandatory' => (isset($object->userassigned[$object->userownerid]['mandatory']) ? $object->userassigned[$object->userownerid]['mandatory'] : null)
2331 );
2332 }
2333 if (!empty($object->userassigned)) { // Now concat assigned users
2334 // Restore array with key with same value than param 'id'
2335 $tmplist1 = $object->userassigned;
2336 foreach ($tmplist1 as $key => $val) {
2337 if ($val['id'] && $val['id'] != $object->userownerid) {
2338 $listofuserid[$val['id']] = $val;
2339 }
2340 }
2341 }
2342 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
2343 } else {
2344 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
2345 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
2346 }
2347 }
2348
2349 $listofcontactid = $object->socpeopleassigned; // Contact assigned
2350 $listofotherid = $object->otherassigned; // Other undefined email (not used yet)
2351
2352 print '<tr><td class="nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
2353 print '<div class="assignedtouser">';
2354 print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner);
2355 print '</div>';
2356 /*if (in_array($user->id,array_keys($listofuserid)))
2357 {
2358 print '<div class="myavailability">';
2359 print $langs->trans("MyAvailability").': <input id="transparency" type="checkbox" name="transparency"'.($listofuserid[$user->id]['transparency']?' checked':'').'>'.$langs->trans("Busy");
2360 print '</div>';
2361 }*/
2362 print '</td></tr>';
2363
2364 // Tags-Categories
2365 if (isModEnabled('category')) {
2366 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
2367 print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
2368 print "</td></tr>";
2369 }
2370
2371 print '</table>';
2372
2373
2374 print '<br>';
2375
2376
2377 print '<table class="border tableforfield centpercent">';
2378
2379 // Status
2380 print '<tr><td class="nowrap">'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td><td colspan="3">';
2381 $percent = GETPOSTISSET("percentage") ? GETPOSTINT("percentage") : $object->percentage;
2382 $formactions->form_select_status_action('formaction', (string) $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300');
2383 print '</td></tr>';
2384
2385 if (isModEnabled("societe")) {
2386 // Related company
2387 print '<tr><td class="titlefieldcreate">'.$langs->trans("ActionOnCompany").'</td>';
2388 print '<td>';
2389 print '<div>';
2390 $events = []; // 'method'=parameter action of url, 'url'=url to call that return new list of contacts
2391 $events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
2392 // TODO Refresh also list of project if conf PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY not defined with list linked to socid ?
2393 // FIXME If we change company, we may get a project that does not match
2394 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($object->socid, 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300');
2395 print '</div>';
2396 print '</td></tr>';
2397
2398 // Related contact
2399 print '<tr><td>'.$langs->trans("ActionOnContact").'</td><td>';
2400 print '<div class="maxwidth200onsmartphone">';
2401
2402 print img_picto('', 'contact', 'class="paddingrightonly"');
2403 if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
2404 // FIXME Use the select_contact supporting the "multiple"
2405 /*
2406 $selected = array_keys($object->socpeopleassigned);
2407 print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
2408 */
2409 $sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
2410 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
2411 print $form->selectcontacts(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : ($object->socid > 0 ? $object->socid : -1), array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', 0, 0, 0, [], 'multiple', 'contactid');
2412 $conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
2413 } else {
2414 // Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
2415 print $form->selectcontacts(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', 0, 0, 0, [], 'multiple', 'contactid');
2416 }
2417 print '</div>';
2418 print '</td>';
2419 print '</tr>';
2420 }
2421
2422 // Project
2423 if (isModEnabled('project')) {
2424 $langs->load("projects");
2425
2426 print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td>';
2427 print img_picto('', 'project', 'class="pictofixedwidth"');
2428 $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');
2429 if ($numprojet == 0) {
2430 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>';
2431 }
2432 print '</td></tr>';
2433 }
2434
2435 // Priority
2436 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
2437 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td>';
2438 print '<input type="text" name="priority" value="'.($object->priority ? $object->priority : '').'" size="5">';
2439 print '</td></tr>';
2440 }
2441
2442 // Object linked
2443 if ($object->fk_project || (!empty($object->elementid) && !empty($object->elementtype))) {
2444 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2445 print '<tr>';
2446 print '<td>'.$langs->trans("LinkedObject").'</td>';
2447
2448 if ($object->elementtype == 'project_task' && isModEnabled('project')) {
2449 print '<td id="project-task-input-container" >';
2450
2451 $urloption = '?action=create&donotclearsession=1'; // we use create not edit for more flexibility
2452 $url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption;
2453
2454 // update task list
2455 ?>
2456 <script type="text/javascript" >
2457 $(document).ready(function () {
2458 $("#projectid").change(function () {
2459 var url = "<?php echo $url; ?>&projectid="+$("#projectid").val();
2460 $.get(url, function(data) {
2461 console.log($( data ).find("#fk_element").html());
2462 if (data) $("#fk_element").html( $( data ).find("#taskid").html() ).select2();
2463 })
2464 });
2465 });
2466 </script>
2467 <?php
2468
2469 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);
2470 print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
2471
2472 print '</td>';
2473 } else {
2474 if (empty($object->elementtype) && empty($object->elementid) && $object->fk_project) {
2475 $projectsListId = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : $object->fk_project;
2476
2477 print '<td id="project-task-input-container" >';
2478
2479 // update task list
2480 ?>
2481 <script type="text/javascript">
2482 $(document).ready(function () {
2483 $("#projectid").change(function () {
2484 var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
2485 console.log("Call url to get new list of tasks: "+url);
2486 $.get(url, function(data) {
2487 console.log(data);
2488 if (data) $("#taskid").html(data).select2();
2489 })
2490 });
2491 });
2492 </script>
2493 <?php
2494
2495 $tid = '';
2496 if (GETPOSTISSET("projecttaskid") && GETPOSTINT("projecttaskid") > 0) {
2497 $tid = GETPOSTINT("projecttaskid");
2498 } elseif (GETPOSTISSET("taskid") && GETPOSTINT("taskid") > 0) {
2499 $tid = GETPOSTINT("taskid");
2500 }
2501
2502 print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
2503
2504 print '</td>';
2505 } else {
2506 print '<td>';
2507 print dolGetElementUrl($object->elementid, $object->elementtype, 1);
2508 print '<input type="hidden" name="fk_element" value="'.$object->elementid.'">';
2509 print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
2510 print '</td>';
2511 }
2512 }
2513
2514 print '</tr>';
2515 }
2516
2517 // Description
2518 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
2519 // Wysiwyg editor
2520 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
2521 $doleditor = new DolEditor('note', $object->note_private, '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
2522 $doleditor->Create();
2523 print '</td></tr>';
2524
2525 // Other attributes
2526 $parameters = [];
2527 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2528 print $hookmanager->resPrint;
2529 if (empty($reshook)) {
2530 print $object->showOptionals($extrafields, 'edit', $parameters);
2531 }
2532
2533 print '</table>';
2534
2535 // Reminders
2536 if ($enablereminders) {
2537 $filteruserid = $user->id;
2538 if ($user->hasRight('agenda', 'allactions', 'read')) {
2539 $filteruserid = 0;
2540 }
2541 $object->loadReminders('', $filteruserid, false);
2542
2543 print '<hr>';
2544
2545 if (count($object->reminders) > 0) {
2546 $checked = 'checked';
2547 $keys = array_keys($object->reminders);
2548 $firstreminderId = array_shift($keys);
2549
2550 $actionCommReminder = $object->reminders[$firstreminderId];
2551 } else {
2552 $checked = '';
2553 $actionCommReminder = new ActionCommReminder($db);
2554 $actionCommReminder->offsetvalue = getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30);
2555 $actionCommReminder->offsetunit = 'i';
2556 $actionCommReminder->typeremind = 'email';
2557 }
2558 $disabled = '';
2559 /*
2560 if ($object->datep < dol_now()) {
2561 //$disabled = 'disabled title="'.dol_escape_htmltag($langs->trans("EventExpired")).'"';
2562 }
2563 */
2564
2565 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>';
2566
2567 print '<div class="reminderparameters" '.(empty($checked) ? 'style="display: none;"' : '').'>';
2568
2569 print '<br>';
2570
2571 print '<table class="border centpercent">';
2572
2573 // Reminder
2574 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
2575 print '<input type="number" name="offsetvalue" class="width50" value="'.$actionCommReminder->offsetvalue.'"> ';
2576 print $form->selectTypeDuration('offsetunit', $actionCommReminder->offsetunit, $TDurationTypesExcluded);
2577 print '</td></tr>';
2578
2579 // Reminder Type
2580 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
2581 print $form->selectarray('selectremindertype', $TRemindTypes, $actionCommReminder->typeremind, 0, 0, 0, '', 0, 0, 0, '', 'minwidth200', 1);
2582 print '</td></tr>';
2583
2584 $hide = '';
2585 if ($actionCommReminder->typeremind == 'browser') {
2586 $hide = 'style="display:none;"';
2587 }
2588
2589 // Mail Model
2590 if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2591 print '<tr '.$hide.'><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
2592 print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (string) $actionCommReminder->fk_email_template);
2593 print '</td></tr>';
2594 }
2595
2596 print '</table>';
2597 ?>
2598 <script type="text/javascript">
2599 $(document).ready(function () {
2600 $("#addreminder").click(function(){
2601 if (this.checked) {
2602 $(".reminderparameters").show();
2603 } else {
2604 $(".reminderparameters").hide();
2605 }
2606 });
2607 $("#selectremindertype").change(function(){
2608 var selected_option = $("#selectremindertype option:selected").val();
2609 if(selected_option == "email") {
2610 $("#select_actioncommsendmodel_mail").closest("tr").show();
2611 } else {
2612 $("#select_actioncommsendmodel_mail").closest("tr").hide();
2613 }
2614 });
2615 });
2616 </script>
2617 <?php
2618
2619 $reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
2620 $reminderDefaultOffset = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
2621 $reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
2622 $reminderDefaultEmailModel = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
2623
2624 print "\n".'<script type="text/javascript">';
2625 print '$(document).ready(function () {
2626 const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
2627 $("#actioncode").change(function(){
2628 var selected_event_type = $("#actioncode option:selected").val();
2629
2630 if (reminderDefaultEventTypes.includes(selected_event_type)) {
2631 $(".reminderparameters").show();
2632 $("#addreminder").prop("checked", true);
2633
2634 // Set period with default reminder period
2635 $("#offsetvalue").val(\''.dol_escape_js($reminderDefaultOffset).'\');
2636 $("#select_offsetunittype_duration").select2("destroy");
2637 $("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
2638 $("#select_offsetunittype_duration").select2();
2639
2640 $("#selectremindertype").select2("destroy");
2641 $("#selectremindertype").val("email");
2642 $("#selectremindertype").select2();
2643
2644 // Set default reminder mail model
2645 $("#select_actioncommsendmodel_mail").closest("tr").show();
2646 $("#select_actioncommsendmodel_mail").select2("destroy");
2647 $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js($reminderDefaultEmailModel).'\');
2648 $("#select_actioncommsendmodel_mail").select2();
2649 }
2650 });
2651 })';
2652 print '</script>'."\n";
2653 print '</div>'; // End of div for reminderparameters
2654 }
2655
2656 print dol_get_fiche_end();
2657
2658 print $form->buttonsSaveCancel();
2659
2660 print '</form>';
2661 } else {
2662 print dol_get_fiche_head($head, 'card', $langs->trans("Action"), -1, 'action');
2663
2664 $formconfirm = '';
2665
2666 // Clone event
2667 if ($action == 'clone') {
2668 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.GETPOST('id'), $langs->trans('ToClone'), $langs->trans('ConfirmCloneEvent', $object->label), 'confirm_clone', [], 'yes', 1);
2669 }
2670
2671 // Call Hook formConfirm
2672 $parameters = [];
2673 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2674 if (empty($reshook)) {
2675 $formconfirm .= $hookmanager->resPrint;
2676 } elseif ($reshook > 0) {
2677 $formconfirm = $hookmanager->resPrint;
2678 }
2679
2680 // Print form confirm
2681 print $formconfirm;
2682
2683 $linkback = '';
2684 // Link to other agenda views
2685 $linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&restore_lastsearch_values=1">';
2686 $linkback .= img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="pictoactionview pictofixedwidth"');
2687 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("BackToList").'</span>';
2688 $linkback .= '</a>';
2689 $linkback .= '</li>';
2690 $linkback .= '<li class="noborder litext">';
2691 $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').'">';
2692 $linkback .= img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="pictoactionview pictofixedwidth"');
2693 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewCal").'</span>';
2694 $linkback .= '</a>';
2695 $linkback .= '</li>';
2696 $linkback .= '<li class="noborder litext">';
2697 $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').'">';
2698 $linkback .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview pictofixedwidth"');
2699 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewWeek").'</span>';
2700 $linkback .= '</a>';
2701 $linkback .= '</li>';
2702 $linkback .= '<li class="noborder litext">';
2703 $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').'">';
2704 $linkback .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview pictofixedwidth"');
2705 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewDay").'</span>';
2706 $linkback .= '</a>';
2707 $linkback .= '</li>';
2708 $linkback .= '<li class="noborder litext">';
2709 $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').'">';
2710 $linkback .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview pictofixedwidth"');
2711 $linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewPerUser").'</span>';
2712 $linkback .= '</a>';
2713
2714 // Add more views from hooks
2715 $parameters = [];
2716 $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
2717 if (empty($reshook)) {
2718 $linkback .= $hookmanager->resPrint;
2719 } elseif ($reshook > 1) {
2720 $linkback = $hookmanager->resPrint;
2721 }
2722
2723 //$linkback.=$out;
2724
2725 $morehtmlref = '<div class="refidno">';
2726 // Thirdparty
2727 //$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
2728 // Project
2729 if (isModEnabled('project')) {
2730 $langs->load("projects");
2731 //$morehtmlref .= '<br>';
2732 if ($usercancreate) {
2733 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2734 if ($action != 'classify') {
2735 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2736 }
2737 $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');
2738 } else {
2739 if (!empty($object->fk_project)) {
2740 $proj = new Project($db);
2741 $proj->fetch($object->fk_project);
2742 $morehtmlref .= $proj->getNomUrl(1);
2743 if ($proj->title) {
2744 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2745 }
2746 }
2747 }
2748 }
2749 $morehtmlref .= '</div>';
2750
2751
2752 dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'id', 'ref', $morehtmlref);
2753
2754 print '<div class="fichecenter">';
2755 print '<div class="fichehalfleft">';
2756
2757 print '<div class="underbanner clearboth"></div>';
2758
2759 // Show event in view mode
2760 print '<table class="border tableforfield centpercent">';
2761
2762 // Type
2763 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
2764 print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td><td>';
2765 $labeltype = ($langs->transnoentities("Action".$object->type_code) != "Action".$object->type_code) ? $langs->transnoentities("Action".$object->type_code) : $object->type_label;
2766 $labeltoshow = $labeltype;
2767 if ($object->code) {
2768 $labeltoshow .= ' ('.$object->code.')';
2769 }
2770 print $object->getTypePicto('pictofixedwidth paddingright', $labeltoshow);
2771 print $labeltype;
2772 print '</td></tr>';
2773 }
2774
2775 // Full day event
2776 print '<tr><td class="titlefieldmiddle">'.$langs->trans("EventOnFullDay").'</td><td>'.yn($object->fulldayevent ? 1 : 0, 3).'</td></tr>';
2777
2778 $rowspan = 4;
2779 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2780 $rowspan++;
2781 }
2782
2783 // Date start
2784 print '<tr><td>'.$langs->trans("DateActionStart").'</td><td title="'.dol_print_date($object->datep, 'dayhoursec', 'tzuserrel').'">';
2785 // Test a date before the 27 march and one after
2786 //print dol_print_date($object->datep, 'dayhour', 'gmt');
2787 //print dol_print_date($object->datep, 'dayhour', 'tzuser');
2788 //print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
2789 if (empty($object->fulldayevent)) {
2790 print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
2791 } else {
2792 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2793 print dol_print_date($object->datep, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
2794 }
2795 if ($object->percentage == 0 && $object->datep && $object->datep < ($now - $delay_warning)) {
2796 print img_warning($langs->trans("Late"));
2797 }
2798 print '</td>';
2799 print '</tr>';
2800
2801 // Date end
2802 print '<tr><td>'.$langs->trans("DateActionEnd").'</td><td title="'.dol_print_date($object->datef, 'dayhoursec', 'tzuserrel').'">';
2803 if (empty($object->fulldayevent)) {
2804 print dol_print_date($object->datef, 'dayhour', 'tzuserrel');
2805 } else {
2806 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
2807 print dol_print_date($object->datef, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
2808 }
2809 if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now - $delay_warning)) {
2810 print img_warning($langs->trans("Late"));
2811 }
2812 print '</td></tr>';
2813
2814 // Recurring event (into a series)
2815 if ($object->recurid) {
2816 print '<tr><td class="titlefieldmiddle">'.$langs->trans("RecurringEvent").'</td><td>';
2817 print img_picto($langs->trans("EventPartOfARecurringSerie", $object->recurid), 'recurring', 'class="pictofixedwidth"');
2818 $reg = [];
2819 if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) {
2820 print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
2821 }
2822 if (preg_match('/FREQ=YEARLY_BYYEARMONTHDAY(\d+)/', $object->recurrule, $reg)) {
2823 print $langs->trans("EveryYear").' <span class="opacitymedium small">('.$langs->trans("DayOfYear").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
2824 }
2825 print '</td></tr>';
2826 }
2827
2828 // Location
2829 if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
2830 print '<tr><td>'.$langs->trans("Location").'</td><td>'.$object->location.'</td></tr>';
2831 }
2832
2833 // Assigned to user
2834 print '<tr><td class="nowrap">'.$langs->trans("ActionAssignedTo").'</td><td>';
2835 $listofuserid = [];
2836 if (empty($donotclearsession)) {
2837 if ($object->userownerid > 0) {
2838 $listofuserid[$object->userownerid] = array(
2839 'id' => $object->userownerid,
2840 'transparency' => $object->transparency, // Force transparency on owner from property of event
2841 'answer_status' => $object->userassigned[$object->userownerid]['answer_status'],
2842 'mandatory' => $object->userassigned[$object->userownerid]['mandatory']
2843 );
2844 }
2845 if (!empty($object->userassigned)) { // Now concat assigned users
2846 // Restore array with key with same value than param 'id'
2847 $tmplist1 = $object->userassigned;
2848 foreach ($tmplist1 as $key => $val) {
2849 if ($val['id'] && $val['id'] != $object->userownerid) {
2850 $listofuserid[$val['id']] = $val;
2851 }
2852 }
2853 }
2854 $_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
2855 } else {
2856 if (!empty($_SESSION[$sessionkeyassignedtouser])) {
2857 $listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
2858 }
2859 }
2860
2861 $listofcontactid = []; // not used yet
2862 $listofotherid = []; // not used yet
2863 print '<div class="assignedtouser">';
2864 print $form->select_dolusers_forevent('view', 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, '', ($object->datep != $object->datef) ? 1 : 0, $listofuserid, $listofcontactid, $listofotherid);
2865 print '</div>';
2866 /*
2867 if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid)))
2868 {
2869 print '<div class="myavailability">';
2870 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
2871 print '</div>';
2872 }
2873 */
2874 print ' </td></tr>';
2875
2876 // Categories
2877 if (isModEnabled('category')) {
2878 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
2879 print $form->showCategories($object->id, Categorie::TYPE_ACTIONCOMM, 1);
2880 print "</td></tr>";
2881 }
2882
2883 print '</table>';
2884
2885 print '</div>';
2886
2887 print '<div class="fichehalfright">';
2888
2889 print '<div class="underbanner clearboth"></div>';
2890 print '<table class="border tableforfield centpercent">';
2891
2892 if (isModEnabled("societe")) {
2893 // Related company
2894 print '<tr><td class="titlefield">'.$langs->trans("ActionOnCompany").'</td>';
2895 print '<td>'.(is_object($object->thirdparty) && $object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : ('<span class="opacitymedium">'.$langs->trans("None").'</span>'));
2896 if (is_object($object->thirdparty) && $object->thirdparty->id > 0 && $object->type_code == 'AC_TEL') {
2897 if ($object->thirdparty->fetch($object->thirdparty->id)) {
2898 print "<br>".dol_print_phone($object->thirdparty->phone);
2899 }
2900 }
2901 print '</td></tr>';
2902
2903 // Related contact
2904 print '<tr><td>'.$langs->trans("ActionOnContact").'</td>';
2905 print '<td>';
2906
2907 if (!empty($object->socpeopleassigned)) {
2908 foreach ($object->socpeopleassigned as $cid => $Tab) {
2909 $contact = new Contact($db);
2910 $result = $contact->fetch($cid);
2911
2912 if ($result < 0) {
2913 dol_print_error($db, $contact->error);
2914 }
2915
2916 if ($result > 0) {
2917 print $contact->getNomUrl(1);
2918 if ($object->type_code == 'AC_TEL') {
2919 if (!empty($contact->phone_pro)) {
2920 print '('.dol_print_phone($contact->phone_pro).')';
2921 }
2922 }
2923 print '<div class="paddingright"></div>';
2924 }
2925 }
2926 } else {
2927 print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
2928 }
2929 print '</td></tr>';
2930 }
2931
2932 // Priority
2933 if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
2934 print '<tr><td class="nowrap" class="titlefield">' . $langs->trans("Priority") . '</td><td>';
2935 print($object->priority ? $object->priority : '');
2936 print '</td></tr>';
2937 }
2938
2939 // Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table
2940 // for such objects because there is already a dedicated field into table llx_actioncomm.
2941 if (!empty($object->elementid) && !empty($object->elementtype) && !in_array($object->elementtype, array('societe', 'contact', 'project'))) {
2942 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2943 print '<tr><td>'.$langs->trans("LinkedObject").'</td>';
2944 $link = dolGetElementUrl($object->elementid, $object->elementtype, ($object->elementtype == 'user' ? -1 : 1));
2945 print '<td>';
2946 if (empty($link)) {
2947 print '<span class="opacitymedium">'.$langs->trans("ObjectDeleted").'</span>';
2948 } else {
2949 print $link;
2950 }
2951 print '</td></tr>';
2952 }
2953
2954 //mail information
2955 if (!empty($object->email_msgid)) {
2956 print '<tr><td>'.$langs->trans('MailTopic').'</td>';
2957 print '<td>'.dol_escape_htmltag($object->email_subject).'</td></tr>';
2958 print '<tr><td>'.$langs->trans('MailFrom').'</td>';
2959 print '<td>'.dol_escape_htmltag($object->email_from).'</td></tr>';
2960 print '<tr><td>'.$langs->trans('MailTo').'</td>';
2961 print '<td>'.dol_escape_htmltag($object->email_to).'</td></tr>';
2962 if (!empty($object->email_tocc)) {
2963 print '<tr><td>'.$langs->trans('MailCC').'</td>';
2964 print '<td>'.dol_escape_htmltag($object->email_tocc).'</td></tr>';
2965 }
2966 }
2967
2968 // Description
2969 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td class="wordbreak sensiblehtmlcontent">';
2970 print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private));
2971 print '</td></tr>';
2972
2973 // Other attributes
2974 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2975
2976 // Reminders
2977 if ($enablereminders) {
2978 $filteruserid = $user->id;
2979 if ($user->hasRight('agenda', 'allactions', 'read')) {
2980 $filteruserid = 0;
2981 }
2982 $object->loadReminders('', $filteruserid, false);
2983
2984 print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Reminders").'</td><td>';
2985
2986 if (count($object->reminders) > 0) {
2987 $tmpuserstatic = new User($db);
2988
2989 foreach ($object->reminders as $actioncommreminderid => $actioncommreminder) {
2990 print $TRemindTypes[$actioncommreminder->typeremind]['label'];
2991 if ($actioncommreminder->fk_user > 0) {
2992 $tmpuserstatic->fetch($actioncommreminder->fk_user);
2993 print ' ('.$tmpuserstatic->getNomUrl(0, '', 0, 0, 16).')';
2994 }
2995 print ' - '.$actioncommreminder->offsetvalue.' '.$TDurationTypes[$actioncommreminder->offsetunit];
2996
2997 if ($actioncommreminder->status == $actioncommreminder::STATUS_TODO) {
2998 print ' - <span class="opacitymedium">';
2999 print $langs->trans("NotSent");
3000 print ' </span>';
3001 } elseif ($actioncommreminder->status == $actioncommreminder::STATUS_DONE) {
3002 print ' - <span class="opacitymedium">';
3003 print $langs->trans("Done");
3004 print ' </span>';
3005 } elseif ($actioncommreminder->status == $actioncommreminder::STATUS_ERROR) {
3006 print ' - <span class="opacitymedium">';
3007 print $form->textwithpicto($langs->trans("Error"), $actioncommreminder->lasterror);
3008 print ' </span>';
3009 }
3010 print '<br>';
3011 }
3012 }
3013
3014 print '</td></tr>';
3015 }
3016
3017 print '</table>';
3018
3019 print '</div>';
3020 print '</div>';
3021 print '<div class="clearboth"></div>';
3022
3023 print dol_get_fiche_end();
3024 }
3025
3026
3027 /*
3028 * Action bar
3029 */
3030 print '<div class="tabsAction">';
3031
3032 $parameters = [];
3033 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3034 if (empty($reshook)) {
3035 if ($action != 'edit') {
3036 if ($user->hasRight('agenda', 'allactions', 'create') ||
3037 (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
3038 print '<div class="inline-block divButAction"><a class="butAction" href="card.php?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Modify").'</a></div>';
3039 } else {
3040 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Modify").'</a></div>';
3041 }
3042
3043 if ($user->hasRight('agenda', 'allactions', 'create') ||
3044 (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
3045 print '<div class="inline-block divButAction"><a class="butAction butActionClone" href="card.php?action=clone&object='.$object->element.'&id='.$object->id.'">'.$langs->trans("ToClone").'</a></div>';
3046 } else {
3047 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("ToClone").'</a></div>';
3048 }
3049
3050 if ($usercandelete) {
3051 print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Delete").'</a></div>';
3052 } else {
3053 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Delete").'</a></div>';
3054 }
3055 }
3056 }
3057
3058 print '</div>';
3059
3060 if ($action != 'edit') {
3061 if (!getDolGlobalString('AGENDA_DISABLE_BUILDDOC')) {
3062 print '<div class="clearboth"></div><div class="fichecenter"><div class="fichehalfleft">';
3063 print '<a name="builddoc"></a>'; // ancre
3064
3065 // Generated documents
3066 $filedir = $conf->agenda->multidir_output[$conf->entity].'/'.$object->id;
3067 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3068
3069 $genallowed = $user->hasRight('agenda', 'myactions', 'read');
3070 $delallowed = $user->hasRight('agenda', 'myactions', 'create');
3071
3072 print $formfile->showdocuments('actions', (string) $object->id, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 0, 0, '', '', '', $langs->getDefaultLang());
3073
3074 if (getDolGlobalString('AGENDA_ENABLE_LINKED_ELEMENTS')) {
3075 // Show links to link elements
3076 $tmparray = $form->showLinkToObjectBlock($object, [], array('myobject'), 1);
3077 if (is_array($tmparray)) {
3078 $linktoelem = $tmparray['linktoelem'];
3079 $htmltoenteralink = $tmparray['htmltoenteralink'];
3080 print $htmltoenteralink;
3081 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
3082 } else {
3083 // backward compatibility
3084 $somethingshown = $form->showLinkedObjectBlock($object, $tmparray);
3085 }
3086 }
3087 print '</div><div class="fichehalfright">';
3088
3089 print '</div></div>';
3090 }
3091 }
3092}
3093
3094// End of page
3095llxFooter();
3096$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
$object ref
Definition info.php:90
Class to manage agenda events (actions)
Class for ActionCommReminder.
Class to manage different types of events.
Class to manage contact/addresses.
Class to manage a WYSIWYG editor.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:168
dol_get_first_day_week($day, $month, $year, $gm=false)
Return first day of week for a date.
Definition date.lib.php:679
num_between_day($timestampStart, $timestampEnd, $lastday=0)
Function to return number of days between two dates (date must be UTC date !) Example: 2012-01-01 201...
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:435
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dolGetElementUrl($objectid, $objecttype, $withpicto=0, $option='')
Return link url to an object.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
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.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
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)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
treeview li table
No Email.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:134
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.