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