* FIX Drag and drop of a file reports a wrong error, or none at all
The error handler of dragAndDropFileUpload() had three defects that all end on
the user believing the file was attached when it was not.
- The first assignment of the message was dead code, there was no return after
the test on the http code 403, so a refusal was reported as a generic error.
- The key ErrorUploadPermissionDenied it used exists in no language file, so
the raw key was shown.
- JSON.parse() was called with no try/catch on an answer that is not always a
json, a fatal error of the endpoint or a request over post_max_size for
example. The exception left the user on a page with no message at all.
- An empty list of files was treated as a success, while it means the endpoint
stored nothing.
The value of PHP_SELF is also escaped before it is written into the 6 generated
javascript strings. It holds the path info of the request on a server that
accepts it, so it is a user input. dol_escape_js() is called with the mode that
escapes a double quote by a double quote, the strings being delimited by double
quotes, and the sequence '</' is escaped too because the function does not do it
and the path info could otherwise close the script tag and open one of its own.
Adds the key ErrorOnAtLeastOneFileUpload to en_US, used when some files of a
batch failed and some did not.
* FIX getMultidirOutput returns a directory the Documents tab does not read
Four defects of the same function, all ending on a file stored where the user
will never see it, or written outside the documents directory.
- The ref of the project of a task was only passed through dol_sanitizePathName(),
which keeps a slash, a colon and the accented chars, while projet/tasks/document.php
sanitizes it with dol_sanitizeFileName(). A project ref holding a slash even
created an extra level of directory. Measured on real databases: 304 projects
over 330 hold a slash on one of them, carrying 701 tasks over 824.
- The same case calls $object->fetchProject() with no guard, while the signature
of the function accepts an object that is not a CommonObject, and even a null
when a module is given. Such a caller gets a fatal error where it expects the
error string. No core caller is in that case today, an external module or a
hook can be.
- The entity of the object may have no declared directory, an object shared by
another entity for example. The undefined index returned a relative path, so
the caller read or wrote under the web root. The current entity is used
instead, and the fallback is logged because the directory is then not the one
of the entity of the object, which matters for a caller that deletes files.
- When the current entity has no declared directory either, the fallback
returned the sub directory alone, again a relative path. The same error than
for a module that declares no directory at all is now returned.
Adds the sub directory of a partnership and of a stock transfer, which their own
document tabs already read.
* FIX getElementProperties answers wrong properties for 9 elements
A customer payment, a supplier payment, a various payment, a stock transfer and
the 4 objects of the hrm module had no properties at all, or wrong ones, so any
caller that resolves a class, a table or a document directory from an element
failed on them.
- payment, payment_supplier and payment_various had no branch. The branch of a
customer payment tests $elementType and not $element, because the rule on the
elements named myobject_mysubobject rewrites $element to 'payment' for
'payment_salary' too, which is stored somewhere else.
- job, position, skill and evaluation answered a wrong table (hrm_job_user for
a position, and so on) and no sub directory, while their document tabs read
one named after the element.
- stocktransfer answered an empty classname, because it is not the ucfirst() of
the element, so a caller doing new $classname($db) ended on a fatal error.
- The sub directory was concatenated even when the module is disabled and the
directory is empty, which answered a path at the root of the file system.
- A contact and a conference are stored into a sub directory their tab reads.
isModEnabled('invoice') is tested for a customer payment: there is no module
named 'compta', so testing it was always false, while $conf->compta->payment is
set unconditionally by Conf::setValues() and could not be used as a proxy.
* FIX Access refused to everyone on 11 objects of the core
restrictedArea() and checkUserAccessToObject() refuse the access to objects that
no permission and no rule can match, whatever the user, an administrator
included.
- The hrm module declares no permission at its first level, only 'all', and the
stocktransfer module only 'stocktransfer'. A check on the module itself
therefore tests a permission that does not exist. The mapping is the same one
as into User::hasRight().
- The module of an event organization declares no permission at all, its whole
permission block being commented out on purpose, and its cards check the
parent project instead. The feature is mapped onto that project, with the two
guards the card has: an external user is refused, and so is a conference with
no parent project, whose id of 0 would otherwise grant an access with no check
on the record at all.
- The default rule of checkUserAccessToObject() builds its sql on the columns
entity and fk_soc of the table. llx_asset, llx_paiement, llx_paiementfourn and
llx_workstation_workstation have no fk_soc, and llx_hrm_job, llx_hrm_job_user
and llx_hrm_skill have neither. The sql failed, so the access was refused to
every user this rule applies to. These tables are now checked on their entity
only, which is what the $check rule already does for the same class of tables,
and the 3 tables of hrm can be checked on nothing at all. The rule is selected
on the table and not on the element, because $object is an id and not an
object for most of the callers, the cards of an asset and of a workstation
included, which are broken today for any user without the permission to see
all third parties.
- An external user is refused explicitly on those tables: none of these objects
is linked to a third party, so the default rule refused him through a link
that does not exist, and the rules that replace it do not look at the third
party of the user at all.
Measured on a vanilla instance with 5 profiles, an administrator, an internal
user with every right, one without the permission to see all third parties, one
that is not a sales representative of the third party of the object, and an
external user: the 11 objects go from refused to granted for the internal users
and stay refused for the external one, and the 26 other elements answer exactly
the same for the 5 profiles.
* FIX A file dropped on a card is lost, or reported as refused when it was stored
FileUpload stores the file into a directory that the "Attached files" tab of the
object never reads, so the user attaches a file that no screen will ever show,
and nothing is indexed in database to find it back. Measured on real databases:
216487 thirdparties over 216887 and 157852 products over 280319 are in that case
on the cards that already enable the drag and drop.
- The directory of the object is now forged with get_exdir(), the way the tabs
do: it always uses the id for a thirdparty, whose ref is a company name and is
not unique, and it falls back on the id when the ref is empty. The sub
directory of the module is read with getMultidirOutput(), which knows the
elements that store their documents into one. That function does not return
an empty string when it fails but a string starting with 'error-', so only an
absolute path is accepted: writing into that string would create the files
under the web root.
- fetchObjectByElement() returns an object even when fetch() returned 0. The
object was then not loaded, and the file was stored at the root of the
directory of the module, out of any object. The constructor now throws, and
the endpoint answers the error with the same json contract than a successful
call so that the caller can show it, instead of a fatal error and an http 500.
- An attachment of the same name was silently overwritten, dol_move_uploaded_file()
being called with $allowoverwrite = 1 while the name was checked before the
ref of the object was added as a prefix. The check is done again on the final
name, and on the .noexe suffixed name too, which that function appends to an
executable file.
- An executable file was renamed with that .noexe suffix and then reported as an
error, while it was correctly stored.
- The endpoint called restrictedArea() with an empty feature when the element is
unknown, and the loop of that function then takes no branch at all and grants
the access with no check. It refuses before, with the same http code and the
same message than a refusal, so that a user cannot tell an object that exists
but is not allowed from an object that does not exist. The refusal of an
external user on an object of another third party answered a message of its
own, which allowed the same enumeration.
Comes with the tests of the path resolution, of the fallback of get_exdir(), of
the rejection of the error string of getMultidirOutput(), and of the file name
deduplication.
* FIX Remove the drop area from 13 cards where dropping a file is harmful
Two distinct groups, both of them removing a drop area that only produces a
result the user does not want.
7 pages have no "Attached files" tab at all, so a file dropped on them can be
reached by no screen: a fiscal year and its info page, an accounting model, a
webhook trigger history, an intracomm report, a bookcal calendar and its booking
list. Measured: 4 of them accepted the upload and wrote an orphan file, the
accounting model wrote it at the root of the directory of the module, out of any
object, and the 2 bookcal ones answered an http 500.
6 cards print their tabs inside their edit form, so the drop area covered that
form: a product, an expense report, a VAT payment, a social contribution, a loan
and a salary. Dropping a file there reloads the page, which discards what the
user is typing. A product and an expense report have a second call for the read
only view, so the drop area is only removed from the call of the edit branch;
the 4 others share a single call between both views, so the parameter is now
conditional.
* NEW Drag and drop a file on the 23 remaining cards
Every card of the core that owns an "Attached files" tab can now receive a file
by drag and drop, which was the case of 32 of them only. The 23 added here are
an asset, an event, a various payment, a customer payment, a contact, a donation,
a conference or booth, a shipment, a supplier payment, a leave request, an
evaluation, a job, a position, a skill, a knowledge record, a manufacturing
order, a partnership, a lot, a stock transfer, a task, a reception, a resource
and a workstation.
The tab bar of a leave request and of a resource is printed inside their edit
form, so the drop area is not enabled there: dropping a file reloads the page,
which would discard what the user is typing. The card of a supplier payment
prints its tab bar even when the object was not loaded, so the drop area is only
enabled when it is.
* FIX getMultidirOutput refuses an entity with no directory instead of falling back [skip-claudemd]
The previous revision of this PR fell back on the directory of the current
entity when the entity of the object had none, with a LOG_WARNING. On a
multicompany install that made a caller read, write and above all delete
files in the directory of another entity. Refuse instead: the function
already answers 'error-diroutput-not-defined-for-this-object' when the
module declares no directory at all, so the caller has one behaviour to
handle, not two.
The entity is cast to int, which is what the array index needs and what
silences the four PhanTypeMismatchDimFetchNullable this function reported.
---------
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
3096 lines
127 KiB
PHP
3096 lines
127 KiB
PHP
<?php
|
|
/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
|
* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
|
|
* Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
|
|
* Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
|
|
* Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
|
|
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
|
* Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
|
|
* Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
|
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
|
|
* Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
|
|
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/comm/action/card.php
|
|
* \ingroup agenda
|
|
* \brief Page for event card
|
|
*/
|
|
|
|
// Load Dolibarr environment
|
|
require '../../main.inc.php';
|
|
/**
|
|
* @var Conf $conf
|
|
* @var DoliDB $db
|
|
* @var ExtraFields $extrafields
|
|
* @var HookManager $hookmanager
|
|
* @var Translate $langs
|
|
* @var User $user
|
|
*/
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
|
|
|
// Load translation files required by the page
|
|
$langs->loadLangs(["companies", "other", "commercial", "bills", "orders", "agenda", "mails"]);
|
|
|
|
// Get Parameters
|
|
$action = GETPOST('action', 'aZ09');
|
|
$cancel = GETPOST('cancel', 'alpha');
|
|
$backtopage = GETPOST('backtopage', 'alpha');
|
|
$socpeopleassigned = GETPOST('socpeopleassigned', 'array');
|
|
$origin = GETPOST('origin', 'alpha');
|
|
$originid = GETPOSTINT('originid');
|
|
$confirm = GETPOST('confirm', 'alpha');
|
|
|
|
$fulldayevent = GETPOST('fullday', 'alpha');
|
|
|
|
$aphour = GETPOSTINT('aphour');
|
|
$apmin = GETPOSTINT('apmin');
|
|
$p2hour = GETPOSTINT('p2hour');
|
|
$p2min = GETPOSTINT('p2min');
|
|
|
|
$addreminder = GETPOST('addreminder', 'alpha');
|
|
$offsetvalue = GETPOSTINT('offsetvalue');
|
|
$offsetunit = GETPOST('offsetunittype_duration', 'aZ09');
|
|
$remindertype = GETPOST('selectremindertype', 'aZ09');
|
|
$modelmail = GETPOSTINT('actioncommsendmodel_mail');
|
|
$complete = GETPOST('complete', 'alpha'); // 'na' must be allowed
|
|
$private = GETPOST('private', 'alphanohtml');
|
|
if ($complete == 'na' || $complete == -2) {
|
|
$complete = -1;
|
|
}
|
|
|
|
$tzforfullday = null;
|
|
if ($fulldayevent) {
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
// For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
|
|
$datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
$datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
//print $db->idate($datep); exit;
|
|
} else {
|
|
$datep = dol_mktime($aphour, $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
|
|
$datef = dol_mktime($p2hour, $p2min, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
|
|
}
|
|
$reg = [];
|
|
if (GETPOST('datep')) {
|
|
if (GETPOST('datep') == 'now') {
|
|
$datep = dol_now();
|
|
} 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
|
|
$datep = dol_mktime((int) $reg[4], (int) $reg[5], (int) $reg[6], (int) $reg[2], (int) $reg[3], (int) $reg[1], 'tzuserrel');
|
|
} 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'
|
|
$datep = dol_mktime(0, 0, 0, (int) $reg[2], (int) $reg[3], (int) $reg[1], 'tzuserrel');
|
|
}
|
|
}
|
|
|
|
$currentyear = (int) dol_print_date(dol_now(), '%Y');
|
|
|
|
if (GETPOSTISSET("limityear") && GETPOSTINT("limityear") < 2100) {
|
|
$repeateventlimitdate = dol_mktime(23, 59, 59, GETPOSTISSET("limitmonth") ? GETPOSTINT("limitmonth") : 1, GETPOSTISSET("limitday") ? GETPOSTINT("limitday") : 1, GETPOSTINT("limityear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
} else {
|
|
$repeateventlimitdate = dol_mktime(23, 59, 59, 12, 31, $currentyear, $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
}
|
|
|
|
// Security check
|
|
$socid = GETPOSTINT('socid');
|
|
if (empty($socid)) {
|
|
$socid = $user->socid; // External users: fall back to their own company (consistent with other card pages)
|
|
}
|
|
$id = GETPOSTINT('id');
|
|
if ($user->socid && ($socid != $user->socid)) {
|
|
accessforbidden();
|
|
}
|
|
|
|
$error = GETPOST("error");
|
|
$donotclearsession = GETPOST('donotclearsession') ? GETPOST('donotclearsession') : 0;
|
|
// Per-event session keys to avoid cross-tab assignee bleed (see issue #30326).
|
|
// When two tabs edit different events, both used to share the same flat
|
|
// assignedtouser / assignedtoresource session buckets, so saving one event
|
|
// could overwrite its assignees with the working set from the other tab.
|
|
$sessionkeyassignedtouser = 'assignedtouser_'.($id > 0 ? $id : 'new');
|
|
$sessionkeyassignedtoresource = 'assignedtoresource_'.($id > 0 ? $id : 'new');
|
|
|
|
// Initialize Objects
|
|
$object = new ActionComm($db);
|
|
$cactioncomm = new CActionComm($db);
|
|
$contact = new Contact($db);
|
|
$formfile = new FormFile($db);
|
|
|
|
$form = new Form($db);
|
|
$formfile = new FormFile($db);
|
|
$formactions = new FormActions($db);
|
|
|
|
// Load object
|
|
if ($id > 0 && $action != 'add') {
|
|
$ret = $object->fetch($id);
|
|
$ret1 = 0;
|
|
if ($ret > 0) {
|
|
$ret = $object->fetch_optionals();
|
|
$ret1 = $object->fetch_userassigned();
|
|
}
|
|
if ($ret < 0 || $ret1 < 0) {
|
|
dol_print_error(null, $object->error);
|
|
}
|
|
}
|
|
|
|
// fetch optionals attributes and labels
|
|
$extrafields->fetch_name_optionals_label($object->table_element);
|
|
|
|
if (empty($action) && empty($object->id)) {
|
|
$action = 'create';
|
|
}
|
|
|
|
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
|
|
$hookmanager->initHooks(['actioncard', 'globalcard']);
|
|
|
|
$TRemindTypes = [];
|
|
if (getDolGlobalString('AGENDA_REMINDER_BROWSER')) {
|
|
$TRemindTypes['browser'] = [
|
|
'label' => $langs->trans('BrowserPush'),
|
|
'disabled' => (getDolGlobalString('AGENDA_REMINDER_BROWSER') ? 0 : 1),
|
|
'type' => ActionCommReminder::TYPE_USER,
|
|
'data-html' => img_picto('', 'globe', 'class="pictofixedwidth"') . $langs->trans('BrowserPush'),
|
|
];
|
|
}
|
|
if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
|
|
$TRemindTypes['email'] = [
|
|
'label' => $langs->trans('EMail'),
|
|
'disabled' => (getDolGlobalString('AGENDA_REMINDER_EMAIL') ? 0 : 1),
|
|
'type' => ActionCommReminder::TYPE_USER,
|
|
'data-html' => img_picto('', 'email', 'class="pictofixedwidth"') . $langs->trans('EMail'),
|
|
];
|
|
}
|
|
if (getDolGlobalString('AGENDA_REMINDER_SMS')) {
|
|
$langs->load('sms');
|
|
$TRemindTypes['sms'] = [
|
|
'label' => $langs->trans('Sms'),
|
|
'disabled' => (getDolGlobalString('MAIN_SMS_SENDMODE') ? 0 : 1),
|
|
'type' => ActionCommReminder::TYPE_USER,
|
|
'data-html' => img_picto('', 'phoning_mobile', 'class="pictofixedwidth"') . $langs->trans('Sms'),
|
|
];
|
|
}
|
|
$TDurationTypes = $form->getDurationTypes($langs);
|
|
$TDurationTypesExcluded = ['y', 'm', 's'];
|
|
$enablereminders = getDolGlobalString('AGENDA_REMINDER_EMAIL') || getDolGlobalString('AGENDA_REMINDER_BROWSER') || getDolGlobalString('AGENDA_REMINDER_SMS');
|
|
$parameters = [
|
|
'socid' => $socid,
|
|
'TRemindTypes' => &$TRemindTypes,
|
|
'enablereminders' => &$enablereminders,
|
|
'TDurationTypes' => &$TDurationTypes,
|
|
'TDurationTypesExcluded' => &$TDurationTypesExcluded,
|
|
];
|
|
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
}
|
|
|
|
$result = restrictedArea($user, 'agenda', $object, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id');
|
|
|
|
$usercancreate = $user->hasRight('agenda', 'allactions', 'create') || ((empty($object->id) || $object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'));
|
|
$usercandelete = $user->hasRight('agenda', 'allactions', 'delete') || (($object->authorid === $user->id || $object->userownerid === $user->id) && $user->hasRight('agenda', 'myactions', 'delete'));
|
|
|
|
|
|
/*
|
|
* Actions
|
|
*/
|
|
|
|
$listUserAssignedUpdated = false;
|
|
$listResourceAssignedUpdated = false;
|
|
$assignedtouser = [];
|
|
|
|
// Remove user to assigned list
|
|
if (empty($reshook) && (GETPOST('removedassigned') || GETPOST('removedassigned') == '0')) {
|
|
$idtoremove = GETPOST('removedassigned');
|
|
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$tmpassigneduserids = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
} else {
|
|
$tmpassigneduserids = [];
|
|
}
|
|
|
|
foreach ($tmpassigneduserids as $key => $val) {
|
|
if ($val['id'] == $idtoremove || $val['id'] == -1) {
|
|
unset($tmpassigneduserids[$key]);
|
|
}
|
|
}
|
|
|
|
$_SESSION[$sessionkeyassignedtouser] = json_encode($tmpassigneduserids);
|
|
$donotclearsession = 1;
|
|
if ($action == 'add') { // Test on permission not required here
|
|
$action = 'create';
|
|
}
|
|
if ($action == 'update') { // Test on permission not required here
|
|
$action = 'edit';
|
|
}
|
|
|
|
$listUserAssignedUpdated = true;
|
|
}
|
|
// Remove resource to assigned list
|
|
if (empty($reshook) && (GETPOST('removedassignedresource') || GETPOST('removedassignedresource') == '0')) {
|
|
$idtoremove = GETPOST('removedassignedresource');
|
|
|
|
if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
|
|
$tmpassignedresourceids = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
|
|
} else {
|
|
$tmpassignedresourceids = [];
|
|
}
|
|
|
|
foreach ($tmpassignedresourceids as $key => $val) {
|
|
if ($val['id'] == $idtoremove || $val['id'] == -1) {
|
|
unset($tmpassignedresourceids[$key]);
|
|
}
|
|
}
|
|
|
|
$_SESSION[$sessionkeyassignedtoresource] = json_encode($tmpassignedresourceids);
|
|
|
|
if ($action == 'add' && $usercancreate) {
|
|
$action = 'create';
|
|
}
|
|
if ($action == 'update' && $usercancreate) {
|
|
$action = 'edit';
|
|
}
|
|
|
|
$listResourceAssignedUpdated = true;
|
|
}
|
|
|
|
// Add user to assigned list
|
|
if (empty($reshook) && (GETPOST('addassignedtouser') || GETPOST('updateassignedtouser'))) {
|
|
// Add a new user
|
|
if (GETPOST('assignedtouser') > 0) {
|
|
$assignedtouser = [];
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$assignedtouser = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
}
|
|
$assignedtouser[GETPOST('assignedtouser')] = array('id' => GETPOSTINT('assignedtouser'), 'transparency' => GETPOST('transparency'), 'mandatory' => 1);
|
|
$_SESSION[$sessionkeyassignedtouser] = json_encode($assignedtouser);
|
|
}
|
|
$donotclearsession = 1;
|
|
if ($action == 'add' && $usercancreate) {
|
|
$action = 'create';
|
|
}
|
|
if ($action == 'update' && $usercancreate) {
|
|
$action = 'edit';
|
|
}
|
|
|
|
$listUserAssignedUpdated = true;
|
|
}
|
|
|
|
// Add resource to assigned list
|
|
if (empty($reshook) && (GETPOST('addassignedtoresource') || GETPOST('updateassignedtoresource'))) {
|
|
// Add a new user
|
|
if (GETPOST('assignedtoresource') > 0) {
|
|
$assignedtoresource = [];
|
|
if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
|
|
$assignedtoresource = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
|
|
}
|
|
$assignedtoresource[GETPOST('assignedtoresource')] = array('id' => GETPOSTINT('assignedtoresource'), 'transparency' => GETPOST('transparency'), 'mandatory' => 1);
|
|
$_SESSION[$sessionkeyassignedtoresource] = json_encode($assignedtoresource);
|
|
}
|
|
$donotclearsession = 1;
|
|
if ($action == 'add' && $usercancreate) {
|
|
$action = 'create';
|
|
}
|
|
if ($action == 'update' && $usercancreate) {
|
|
$action = 'edit';
|
|
}
|
|
|
|
$listResourceAssignedUpdated = true;
|
|
}
|
|
|
|
// Link to a project
|
|
if (empty($reshook) && $action == 'classin' && ($user->hasRight('agenda', 'allactions', 'create') ||
|
|
(($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create')))) {
|
|
//$object->fetch($id);
|
|
$object->setProject(GETPOSTINT('projectid'));
|
|
}
|
|
|
|
// Action clone object
|
|
if (empty($reshook) && $action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
|
|
// @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp
|
|
if (1 == 0 && !GETPOST('clone_content') && !GETPOST('clone_receivers')) {
|
|
setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
|
|
} else {
|
|
if ($id > 0) {
|
|
//$object->fetch($id);
|
|
if (!empty($object->socpeopleassigned)) {
|
|
reset($object->socpeopleassigned);
|
|
$object->contact_id = (int) key($object->socpeopleassigned);
|
|
}
|
|
$result = $object->createFromClone($user, GETPOSTINT('socid'));
|
|
if ($result > 0) {
|
|
header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
|
|
exit();
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$action = '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add event
|
|
if (empty($reshook) && $action == 'add' && $usercancreate) {
|
|
$error = 0;
|
|
|
|
if (empty($backtopage)) {
|
|
if ($socid > 0) {
|
|
$backtopage = DOL_URL_ROOT.'/societe/agenda.php?socid='.$socid;
|
|
} else {
|
|
$backtopage = DOL_URL_ROOT.'/comm/action/index.php';
|
|
}
|
|
}
|
|
|
|
if (!empty($socpeopleassigned[0])) {
|
|
$result = $contact->fetch($socpeopleassigned[0]);
|
|
}
|
|
|
|
if ($cancel) {
|
|
header("Location: ".$backtopage);
|
|
exit;
|
|
}
|
|
|
|
$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
|
|
|
|
// Clean parameters
|
|
if ($fulldayevent) {
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
// For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
|
|
$datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
$datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
} else {
|
|
$datep = dol_mktime(GETPOSTINT("aphour"), GETPOSTINT("apmin"), GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
|
|
$datef = dol_mktime(GETPOSTINT("p2hour"), GETPOSTINT("p2min"), GETPOSTINT("apsec"), GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
|
|
}
|
|
//set end date to now if percentage is set to 100 and end date not set
|
|
$datef = (!$datef && $percentage == 100) ? dol_now() : $datef;
|
|
|
|
// Check parameters
|
|
if (!$datef && $percentage == 100) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
|
|
}
|
|
|
|
if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE') && !GETPOST('label')) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Title")), null, 'errors');
|
|
}
|
|
|
|
// Initialisation object cactioncomm
|
|
if (GETPOSTISSET('actioncode') && !GETPOST('actioncode', 'aZ09')) { // actioncode is '0'
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
|
|
} else {
|
|
$object->type_code = GETPOST('actioncode', 'aZ09');
|
|
}
|
|
|
|
$listofresourceid = [];
|
|
|
|
if (!$error) {
|
|
// Initialisation of object actioncomm
|
|
$object->priority = GETPOSTISSET("priority") ? GETPOSTINT("priority") : 0;
|
|
$object->fulldayevent = ($fulldayevent ? 1 : 0);
|
|
$object->location = GETPOST("location", 'alphanohtml');
|
|
$object->label = GETPOST('label', 'alphanohtml');
|
|
|
|
if (GETPOST("elementtype", 'alpha')) {
|
|
$elProp = getElementProperties(GETPOST("elementtype", 'alpha'));
|
|
$modulecodetouseforpermissioncheck = $elProp['module'];
|
|
// Keep permission check aligned with rights class aliases (see restrictedArea()).
|
|
$submodulecodetouseforpermissioncheck = $elProp['subelement'];
|
|
|
|
switch ($modulecodetouseforpermissioncheck) {
|
|
case 'productbatch':
|
|
$modulecodetouseforpermissioncheck = 'produit';
|
|
break;
|
|
case 'eventorganization':
|
|
// Event organization relies on Project permissions
|
|
$modulecodetouseforpermissioncheck = 'projet';
|
|
$submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
|
|
break;
|
|
default:
|
|
// No mapping needed, keep original values
|
|
break;
|
|
}
|
|
|
|
$hasPermissionOnLinkedObject = 0;
|
|
if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
|
|
$hasPermissionOnLinkedObject = 1;
|
|
} elseif ($user->hasRight($modulecodetouseforpermissioncheck, $submodulecodetouseforpermissioncheck, 'read')) {
|
|
$hasPermissionOnLinkedObject = 1;
|
|
}
|
|
|
|
if ($hasPermissionOnLinkedObject) {
|
|
$object->fk_element = GETPOSTINT("fk_element");
|
|
$object->elementid = GETPOSTINT("fk_element");
|
|
$object->elementtype = GETPOST("elementtype", 'alpha');
|
|
}
|
|
}
|
|
|
|
if (!GETPOST('label')) {
|
|
if (GETPOST('actioncode', 'aZ09') == 'AC_RDV' && $contact->getFullName($langs)) {
|
|
$object->label = $langs->transnoentitiesnoconv("TaskRDVWith", $contact->getFullName($langs));
|
|
} else {
|
|
if ($langs->trans("Action".$object->type_code) != "Action".$object->type_code) {
|
|
$object->label = $langs->transnoentitiesnoconv("Action".$object->type_code)."\n";
|
|
} else {
|
|
$cactioncomm->fetch($object->type_code);
|
|
$object->label = $cactioncomm->label;
|
|
}
|
|
}
|
|
}
|
|
$object->fk_project = GETPOSTISSET("projectid") ? GETPOSTINT("projectid") : 0;
|
|
|
|
$taskid = GETPOSTINT('taskid');
|
|
if (!empty($taskid)) {
|
|
$taskProject = new Task($db);
|
|
if ($taskProject->fetch($taskid) > 0) {
|
|
$object->fk_project = $taskProject->fk_project;
|
|
}
|
|
|
|
$object->fk_element = $taskid;
|
|
$object->elementid = $taskid;
|
|
$object->elementtype = 'project_task';
|
|
}
|
|
|
|
$object->datep = $datep;
|
|
$object->datef = $datef;
|
|
$object->percentage = $percentage;
|
|
$object->duree = (((int) GETPOST('dureehour') * 60) + (int) GETPOST('dureemin')) * 60;
|
|
|
|
$transparency = (GETPOST("transparency") == 'on' ? 1 : 0);
|
|
|
|
$listofuserid = [];
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
}
|
|
|
|
if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
|
|
$listofresourceid = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
|
|
}
|
|
|
|
$i = 0;
|
|
foreach ($listofuserid as $key => $value) {
|
|
if ($i == 0) { // First entry
|
|
if ($value['id'] > 0) {
|
|
$object->userownerid = $value['id'];
|
|
}
|
|
$object->transparency = $transparency;
|
|
}
|
|
|
|
$object->userassigned[$value['id']] = array('id' => $value['id'], 'transparency' => $transparency);
|
|
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
$object->note_private = trim(GETPOST("note", "restricthtml"));
|
|
|
|
if (GETPOSTISSET("contactid")) {
|
|
$object->contact_id = GETPOSTINT("contactid");
|
|
$object->fetch_contact();
|
|
}
|
|
|
|
if (GETPOSTINT('socid') > 0) {
|
|
$object->socid = GETPOSTINT('socid');
|
|
$object->fetch_thirdparty();
|
|
}
|
|
|
|
// Check parameters
|
|
if (empty($object->userownerid) && empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ActionsOwnedBy")), null, 'errors');
|
|
}
|
|
if ($object->type_code == 'AC_RDV' && ($datep == '' || ($datef == '' && empty($fulldayevent)))) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
|
|
}
|
|
|
|
if (!GETPOST('apyear') && !GETPOST('adyear')) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
|
|
}
|
|
|
|
foreach ($socpeopleassigned as $cid) {
|
|
$object->socpeopleassigned[$cid] = array('id' => $cid);
|
|
}
|
|
if (!empty($object->socpeopleassigned)) {
|
|
reset($object->socpeopleassigned);
|
|
$object->contact_id = key($object->socpeopleassigned);
|
|
}
|
|
|
|
// Fill array 'array_options' with data from add form
|
|
$ret = $extrafields->setOptionalsFromPost(null, $object);
|
|
if ($ret < 0) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'create';
|
|
}
|
|
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
|
|
$dayinyear = dol_print_date($object->datep, '%m%d');
|
|
$dayinmonth = dol_print_date($object->datep, '%d');
|
|
$dayinweek = dol_print_date($object->datep, '%w');
|
|
|
|
$selectedrecurrulefreq = 'no';
|
|
$selectedrecurrulebyyearmonthday = '';
|
|
$selectedrecurrulebymonthday = '';
|
|
$selectedrecurrulebyday = '';
|
|
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
|
|
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'YEARLY') ? "_BYYEARMONTHDAY".((int) $dayinyear) : "";
|
|
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'MONTHLY') ? "_BYMONTHDAY".((int) $dayinmonth) : "";
|
|
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'WEEKLY') ? "_BYDAY".((int) $dayinweek) : "";
|
|
|
|
$reg1 = [];
|
|
$reg2 = [];
|
|
$reg3 = [];
|
|
$reg4 = [];
|
|
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) {
|
|
$selectedrecurrulefreq = $reg1[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg4)) {
|
|
$selectedrecurrulebyyearmonthday = (int) $reg4[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) {
|
|
$selectedrecurrulebymonthday = (int) $reg2[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg3)) {
|
|
$selectedrecurrulebyday = (int) $reg3[1];
|
|
}
|
|
|
|
// Is event recurrent ?
|
|
$eventisrecurring = 0;
|
|
$userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
|
|
if ($userepeatevent && !empty($selectedrecurrulefreq) && $selectedrecurrulefreq != 'no') {
|
|
$eventisrecurring = 1;
|
|
$object->recurid = dol_print_date(dol_now('gmt'), 'dayhourlog', 'gmt');
|
|
$object->recurdateend = dol_mktime(0, 0, 0, GETPOSTINT('limitmonth'), GETPOSTINT('limitday'), GETPOSTINT('limityear'));
|
|
} else {
|
|
unset($object->recurid);
|
|
unset($object->recurrule);
|
|
unset($object->recurdateend);
|
|
}
|
|
|
|
// Creation of action/event
|
|
$idaction = $object->create($user);
|
|
$moreparam = '';
|
|
|
|
if ($idaction > 0) {
|
|
if (!$object->error) {
|
|
if (is_array($listofresourceid) && count($listofresourceid)) {
|
|
foreach ($listofresourceid as $resource_id => $val) {
|
|
$resource_type = 'dolresource';
|
|
$busy = 1;//GETPOSTINT('busy');
|
|
|
|
// Resources association
|
|
if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK')) {
|
|
$eventDateStart = $object->datep;
|
|
$eventDateEnd = $object->datef;
|
|
$isFullDayEvent = $object->fulldayevent;
|
|
if (empty($eventDateEnd)) {
|
|
if ($isFullDayEvent) {
|
|
$eventDateStartArr = dol_getdate($eventDateStart);
|
|
$eventDateStart = dol_mktime(0, 0, 0, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
|
|
$eventDateEnd = dol_mktime(23, 59, 59, $eventDateStartArr['mon'], $eventDateStartArr['mday'], $eventDateStartArr['year']);
|
|
}
|
|
}
|
|
|
|
$sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "element_resources as er";
|
|
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "resource as r ON r.rowid = er.resource_id AND er.resource_type = '" . $db->escape($resource_type) . "'";
|
|
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "actioncomm as ac ON ac.id = er.element_id AND er.element_type = '" . $db->escape($object->element) . "'";
|
|
$sql .= " WHERE er.resource_id = " . ((int) $resource_id);
|
|
$sql .= " AND er.busy = 1";
|
|
$sql .= " AND (";
|
|
|
|
// event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
|
|
$sql .= " (ac.datep <= '" . $db->idate($eventDateStart) . "' AND (ac.datep2 IS NULL OR ac.datep2 >= '" . $db->idate($eventDateStart) . "'))";
|
|
// event date end between ac.datep and ac.datep2
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " OR (ac.datep <= '" . $db->idate($eventDateEnd) . "' AND (ac.datep2 >= '" . $db->idate($eventDateEnd) . "'))";
|
|
}
|
|
// event date start before ac.datep and event date end after ac.datep2
|
|
$sql .= " OR (";
|
|
$sql .= "ac.datep >= '" . $db->idate($eventDateStart) . "'";
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '" . $db->idate($eventDateEnd) . "')";
|
|
}
|
|
$sql .= ")";
|
|
|
|
$sql .= ")";
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$object->error = $db->lasterror();
|
|
$object->errors[] = $object->error;
|
|
} else {
|
|
if ($db->num_rows($resql) > 0) {
|
|
// Resource already in use
|
|
$error++;
|
|
$object->error = $langs->trans('ErrorResourcesAlreadyInUse') . ' : ';
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$object->error .= '<br> - ' . $langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label . ' [' . $obj->ac_id . ']');
|
|
}
|
|
$object->errors[] = $object->error;
|
|
|
|
setEventMessages($object->error, null, 'errors');
|
|
}
|
|
$db->free($resql);
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$res = $object->add_element_resource($resource_id, $resource_type, $busy, $val['mandatory']);
|
|
}
|
|
}
|
|
}
|
|
|
|
unset($_SESSION[$sessionkeyassignedtoresource]);
|
|
|
|
|
|
// Category association
|
|
if (!$error) {
|
|
$categories = GETPOST('categories', 'array');
|
|
$object->setCategories($categories);
|
|
}
|
|
|
|
unset($_SESSION[$sessionkeyassignedtouser]);
|
|
|
|
if ($user->id != $object->userownerid) {
|
|
$moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
|
|
}
|
|
|
|
// Create reminders
|
|
if (!$error && $addreminder == 'on') {
|
|
$actionCommReminder = new ActionCommReminder($db);
|
|
|
|
$dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
|
|
|
|
$actionCommReminder->dateremind = $dateremind;
|
|
$actionCommReminder->typeremind = $remindertype;
|
|
$actionCommReminder->offsetunit = $offsetunit;
|
|
$actionCommReminder->offsetvalue = $offsetvalue;
|
|
$actionCommReminder->status = $actionCommReminder::STATUS_TODO;
|
|
$actionCommReminder->fk_actioncomm = $object->id;
|
|
if ($remindertype == 'email') {
|
|
$actionCommReminder->fk_email_template = $modelmail;
|
|
}
|
|
|
|
// the notification must be created for every user assigned to the event
|
|
foreach ($object->userassigned as $userassigned) {
|
|
$actionCommReminder->fk_user = $userassigned['id'];
|
|
$res = $actionCommReminder->create($user);
|
|
|
|
if ($res <= 0) {
|
|
// If error
|
|
$langs->load("errors");
|
|
$error++;
|
|
setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page.
|
|
/*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0';
|
|
$moreparam .= ($moreparam ? '&' : '').'search_status=-1';
|
|
$moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
|
|
*/
|
|
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
|
|
|
|
// if (!empty($backtopage)) {
|
|
// dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
|
// header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
|
// } elseif ($idaction) {
|
|
// header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
|
|
// } else {
|
|
// header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
|
|
// }
|
|
// exit;
|
|
} else {
|
|
// If error
|
|
$langs->load("errors");
|
|
$error++;
|
|
setEventMessages($langs->trans($object->error), null, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
}
|
|
} else {
|
|
$error++;
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
}
|
|
|
|
// Manage other events in case of recurring event
|
|
if (!$error && $eventisrecurring) {
|
|
$dayoffset = 0;
|
|
$monthoffset = 0;
|
|
$yearoffset = 0;
|
|
// We set first date of recurrence and offsets
|
|
if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
|
|
$firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear"));
|
|
$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');
|
|
$datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after
|
|
$dayoffset = 7;
|
|
$monthoffset = 0;
|
|
$yearoffset = 0;
|
|
} elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) {
|
|
$firstday = $selectedrecurrulebymonthday;
|
|
$firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the month after
|
|
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstmonth, $firstday, GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
$datep = dol_time_plus_duree($datep, 1, 'm');//We begin the month after
|
|
$dayoffset = 0;
|
|
$monthoffset = 1;
|
|
$yearoffset = 0;
|
|
} elseif ($selectedrecurrulefreq == 'YEARLY' && !empty($selectedrecurrulebyyearmonthday)) {
|
|
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
$datep = dol_time_plus_duree($datep, 1, 'y');//We begin the year after
|
|
$dayoffset = 0;
|
|
$monthoffset = 0;
|
|
$yearoffset = 1;
|
|
} else {
|
|
$error++;
|
|
}
|
|
// End date
|
|
// Set date of end of event
|
|
$deltatime = num_between_day($object->datep, $datep);
|
|
// @phan-suppress-next-line PhanPluginSuspiciousParamOrder
|
|
$datef = dol_time_plus_duree($datef, $deltatime, 'd');
|
|
|
|
while ($datep <= $repeateventlimitdate && !$error) {
|
|
$finalobject = clone $object;
|
|
|
|
|
|
$finalobject->datep = $datep;
|
|
$finalobject->datef = $datef;
|
|
// Creation of action/event
|
|
$idaction = $finalobject->create($user);
|
|
|
|
if ($idaction > 0) {
|
|
if (!$finalobject->error) {
|
|
// Category association
|
|
$categories = GETPOST('categories', 'array');
|
|
$finalobject->setCategories($categories);
|
|
|
|
unset($_SESSION[$sessionkeyassignedtouser]);
|
|
|
|
$moreparam = '';
|
|
if ($user->id != $finalobject->userownerid) {
|
|
$moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
|
|
}
|
|
|
|
// Create reminders
|
|
if ($addreminder == 'on') {
|
|
$actionCommReminder = new ActionCommReminder($db);
|
|
|
|
$dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
|
|
|
|
$actionCommReminder->dateremind = $dateremind;
|
|
$actionCommReminder->typeremind = $remindertype;
|
|
$actionCommReminder->offsetunit = $offsetunit;
|
|
$actionCommReminder->offsetvalue = $offsetvalue;
|
|
$actionCommReminder->status = $actionCommReminder::STATUS_TODO;
|
|
$actionCommReminder->fk_actioncomm = $finalobject->id;
|
|
if ($remindertype == 'email') {
|
|
$actionCommReminder->fk_email_template = $modelmail;
|
|
}
|
|
|
|
// the notification must be created for every user assigned to the event
|
|
foreach ($finalobject->userassigned as $userassigned) {
|
|
$actionCommReminder->fk_user = $userassigned['id'];
|
|
$res = $actionCommReminder->create($user);
|
|
|
|
if ($res <= 0) {
|
|
// If error
|
|
$error++;
|
|
$langs->load("errors");
|
|
setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page.
|
|
/*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0';
|
|
$moreparam .= ($moreparam ? '&' : '').'search_status=-1';
|
|
$moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
|
|
*/
|
|
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
|
|
} else {
|
|
// If error
|
|
$error++;
|
|
$langs->load("errors");
|
|
$error = $langs->trans($finalobject->error);
|
|
setEventMessages($error, null, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
}
|
|
} else {
|
|
$error++;
|
|
setEventMessages($finalobject->error, $finalobject->errors, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
}
|
|
|
|
// If event is not recurrent, we stop here
|
|
if (!($userepeatevent && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday"))) {
|
|
break;
|
|
}
|
|
|
|
// increment date for recurrent events
|
|
$datep = dol_time_plus_duree($datep, $dayoffset, 'd');
|
|
$datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
|
$datep = dol_time_plus_duree($datep, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
|
$datef = dol_time_plus_duree($datef, $dayoffset, 'd');
|
|
$datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
|
$datef = dol_time_plus_duree($datef, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
|
}
|
|
}
|
|
|
|
if ($error) {
|
|
$db->rollback();
|
|
} else {
|
|
$db->commit();
|
|
}
|
|
|
|
if (!empty($backtopage) && !$error) {
|
|
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
|
header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
|
} elseif ($idaction) {
|
|
header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
|
|
} else {
|
|
header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
|
|
}
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Action update event
|
|
if (empty($reshook) && $action == 'update' && $usercancreate) {
|
|
if (empty($cancel)) {
|
|
$fulldayevent = GETPOST('fullday');
|
|
$aphour = GETPOSTINT('aphour');
|
|
$apmin = GETPOSTINT('apmin');
|
|
$p2hour = GETPOSTINT('p2hour');
|
|
$p2min = GETPOSTINT('p2min');
|
|
$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
|
|
|
|
// Clean parameters
|
|
if ($aphour == -1) {
|
|
$aphour = '0';
|
|
}
|
|
if ($apmin == -1) {
|
|
$apmin = '0';
|
|
}
|
|
if ($p2hour == -1) {
|
|
$p2hour = '0';
|
|
}
|
|
if ($p2min == -1) {
|
|
$p2min = '0';
|
|
}
|
|
|
|
$object->fetch($id);
|
|
$object->fetch_optionals();
|
|
$object->fetch_userassigned();
|
|
$object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
|
|
|
|
// Clean parameters
|
|
if ($fulldayevent) {
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
// For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
|
|
$datep = dol_mktime(0, 0, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
$datef = dol_mktime(23, 59, 59, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
|
} else {
|
|
if (!GETPOSTISSET('ap') && !GETPOSTISSET('aphour') && !GETPOSTISSET('apmin')) { // If date fields are disabled, we keep old value
|
|
$datep = $object->datep;
|
|
} else {
|
|
$datep = dol_mktime(GETPOSTINT("aphour"), GETPOSTINT("apmin"), GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
|
|
}
|
|
if (!GETPOSTISSET('p2') && !GETPOSTISSET('p2hour') && !GETPOSTISSET('p2min')) { // If date fields are disabled, we keep old value
|
|
$datef = $object->datef;
|
|
} else {
|
|
$datef = dol_mktime(GETPOSTINT("p2hour"), GETPOSTINT("p2min"), GETPOSTINT("apsec"), GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
|
|
}
|
|
}
|
|
|
|
//set end date to now if percentage is set to 100 and end date not set
|
|
$datef = (!$datef && $percentage == 100) ? dol_now() : $datef;
|
|
|
|
if ($object->elementtype == 'ticket') { // code should be TICKET_MSG, TICKET_MSG_PRIVATE, TICKET_MSG_SENTBYMAIL, TICKET_MSG_PRIVATE_SENTBYMAIL
|
|
if ($private) {
|
|
if ($object->code == 'TICKET_MSG') {
|
|
$object->code = 'TICKET_MSG_PRIVATE';
|
|
}
|
|
if ($object->code == 'TICKET_MSG_SENTBYMAIL') {
|
|
$object->code = 'TICKET_MSG_PRIVATE_SENTBYMAIL';
|
|
}
|
|
} else {
|
|
if ($object->code == 'TICKET_MSG_PRIVATE') {
|
|
$object->code = 'TICKET_MSG';
|
|
}
|
|
if ($object->code == 'TICKET_MSG_PRIVATE_SENTBYMAIL') {
|
|
$object->code = 'TICKET_MSG_SENTBYMAIL';
|
|
}
|
|
}
|
|
// type_id and type_code is not modified
|
|
} else {
|
|
$object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm');
|
|
$object->type_code = GETPOST("actioncode", 'aZ09');
|
|
}
|
|
|
|
$object->label = GETPOST("label", "alphanohtml");
|
|
$object->datep = $datep;
|
|
$object->datef = $datef;
|
|
$object->percentage = $percentage;
|
|
$object->priority = GETPOSTINT("priority");
|
|
$object->fulldayevent = GETPOST("fullday") ? 1 : 0;
|
|
$object->location = GETPOST('location', "alphanohtml");
|
|
$object->socid = GETPOSTINT("socid");
|
|
$socpeopleassigned = GETPOST("socpeopleassigned", 'array');
|
|
$object->socpeopleassigned = [];
|
|
foreach ($socpeopleassigned as $cid) {
|
|
$object->socpeopleassigned[$cid] = array('id' => $cid);
|
|
}
|
|
$object->contact_id = GETPOSTINT("contactid");
|
|
if (empty($object->contact_id) && !empty($object->socpeopleassigned)) {
|
|
reset($object->socpeopleassigned);
|
|
$object->contact_id = (int) key($object->socpeopleassigned);
|
|
}
|
|
$object->fk_project = GETPOSTINT("projectid");
|
|
$taskid = GETPOSTINT('taskid');
|
|
if (!empty($taskid)) {
|
|
$taskProject = new Task($db);
|
|
if ($taskProject->fetch($taskid) > 0) {
|
|
$object->fk_project = $taskProject->fk_project;
|
|
}
|
|
|
|
$object->fk_element = $taskid;
|
|
$object->elementid = $taskid;
|
|
$object->elementtype = 'project_task';
|
|
}
|
|
|
|
$object->note_private = trim(GETPOST("note", "restricthtml"));
|
|
|
|
if (GETPOST("elementtype", 'alpha')) {
|
|
$elProp = getElementProperties(GETPOST("elementtype", 'alpha'));
|
|
$modulecodetouseforpermissioncheck = $elProp['module'];
|
|
// Keep permission check aligned with rights class aliases (see restrictedArea()).
|
|
$submodulecodetouseforpermissioncheck = $elProp['subelement'];
|
|
|
|
switch ($modulecodetouseforpermissioncheck) {
|
|
case 'productbatch':
|
|
$modulecodetouseforpermissioncheck = 'produit';
|
|
break;
|
|
case 'eventorganization':
|
|
// Event organization relies on Project permissions
|
|
$modulecodetouseforpermissioncheck = 'projet';
|
|
$submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
|
|
break;
|
|
default:
|
|
// No mapping needed, keep original values
|
|
break;
|
|
}
|
|
|
|
$hasPermissionOnLinkedObject = 0;
|
|
if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
|
|
$hasPermissionOnLinkedObject = 1;
|
|
}
|
|
if ($hasPermissionOnLinkedObject) {
|
|
$object->fk_element = GETPOSTINT("fk_element");
|
|
$object->elementid = GETPOSTINT("fk_element");
|
|
$object->elementtype = GETPOST("elementtype", 'alpha');
|
|
}
|
|
}
|
|
|
|
|
|
$transparency = (GETPOST("transparency") == 'on' ? 1 : 0);
|
|
|
|
// Users
|
|
$listofuserid = [];
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) { // Now concat assigned users
|
|
// Restore array with key with same value than param 'id'
|
|
$tmplist1 = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
foreach ($tmplist1 as $key => $val) {
|
|
if ($val['id'] > 0 && $val['id'] != $assignedtouser) {
|
|
$listofuserid[$val['id']] = $val;
|
|
}
|
|
}
|
|
} else {
|
|
$assignedtouser = (!empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : 0);
|
|
if ($assignedtouser) {
|
|
$listofuserid[$assignedtouser] = array('id' => $assignedtouser, 'mandatory' => 0, 'transparency' => ($user->id == $assignedtouser ? $transparency : '')); // Owner first
|
|
}
|
|
}
|
|
$object->userassigned = [];
|
|
$object->userownerid = 0; // Clear old content
|
|
$i = 0;
|
|
foreach ($listofuserid as $key => $val) {
|
|
if ($i == 0) {
|
|
$object->userownerid = $val['id'];
|
|
}
|
|
$object->userassigned[$val['id']] = array('id' => $val['id'], 'mandatory' => 0, 'transparency' => ($user->id == $val['id'] ? $transparency : ''));
|
|
$i++;
|
|
}
|
|
|
|
$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)
|
|
// TODO store also transparency on owner user
|
|
|
|
// Check parameters
|
|
if (GETPOSTISSET('actioncode') && !GETPOST('actioncode', 'aZ09')) { // actioncode is '0'
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'edit';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
|
|
} else {
|
|
$result = $cactioncomm->fetch(GETPOST('actioncode', 'aZ09'));
|
|
}
|
|
if (empty($object->userownerid)) {
|
|
$error++;
|
|
$donotclearsession = 1;
|
|
$action = 'edit';
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ActionsOwnedBy")), null, 'errors');
|
|
}
|
|
|
|
// Fill array 'array_options' with data from add form
|
|
$ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
|
|
if ($ret < 0) {
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
// check if an event resource is already in use
|
|
if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
|
|
$eventDateStart = $object->datep;
|
|
$eventDateEnd = $object->datef;
|
|
|
|
$sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
|
|
$sql .= " WHERE ac.id <> ".((int) $object->id);
|
|
$sql .= " AND er.resource_id IN (";
|
|
$sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
|
|
$sql .= " WHERE element_id = ".((int) $object->id);
|
|
$sql .= " AND element_type = '".$db->escape($object->element)."'";
|
|
$sql .= " AND busy = 1";
|
|
$sql .= ")";
|
|
$sql .= " AND er.busy = 1";
|
|
$sql .= " AND (";
|
|
|
|
// event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
|
|
$sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
|
|
// event date end between ac.datep and ac.datep2
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
|
|
}
|
|
// event date start before ac.datep and event date end after ac.datep2
|
|
$sql .= " OR (";
|
|
$sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
|
|
}
|
|
$sql .= ")";
|
|
|
|
$sql .= ")";
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$object->error = $db->lasterror();
|
|
$object->errors[] = $object->error;
|
|
} else {
|
|
if ($db->num_rows($resql) > 0) {
|
|
// Resource already in use
|
|
$error++;
|
|
$object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
|
|
}
|
|
$object->errors[] = $object->error;
|
|
}
|
|
$db->free($resql);
|
|
}
|
|
|
|
if ($error) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
|
|
$result = $object->update($user);
|
|
|
|
if ($result > 0) {
|
|
// Category association
|
|
$categories = GETPOST('categories', 'array');
|
|
$object->setCategories($categories);
|
|
|
|
$object->loadReminders($remindertype, 0, false);
|
|
|
|
// If there is reminders, we remove them
|
|
if (!empty($object->reminders)) {
|
|
foreach ($object->reminders as $reminder) {
|
|
if ($reminder->status < 1) { // If already sent, we never remove it
|
|
$reminder->delete($user);
|
|
}
|
|
}
|
|
$object->reminders = [];
|
|
}
|
|
|
|
// Create reminders for every assigned user if reminder is on
|
|
if ($addreminder == 'on') {
|
|
$actionCommReminder = new ActionCommReminder($db);
|
|
|
|
$dateremind = dol_time_plus_duree($datep, -1 * $offsetvalue, $offsetunit);
|
|
|
|
$actionCommReminder->dateremind = $dateremind;
|
|
$actionCommReminder->typeremind = $remindertype;
|
|
$actionCommReminder->offsetunit = $offsetunit;
|
|
$actionCommReminder->offsetvalue = $offsetvalue;
|
|
$actionCommReminder->status = $actionCommReminder::STATUS_TODO;
|
|
$actionCommReminder->fk_actioncomm = $object->id;
|
|
if ($remindertype == 'email') {
|
|
$actionCommReminder->fk_email_template = $modelmail;
|
|
}
|
|
|
|
// the notification must be created for every user assigned to the event
|
|
foreach ($object->userassigned as $userassigned) {
|
|
$actionCommReminder->fk_user = $userassigned['id'];
|
|
|
|
// We update the event, so we recreate the notification event.
|
|
// First we delete all reminders for the user and the type of reminding (all offset dates).
|
|
$sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
|
|
$sqldelete .= " WHERE fk_user = ".((int) $actionCommReminder->fk_user)." AND fk_actioncomm = ".((int) $object->id)." AND typeremind = '".$db->escape($remindertype)."'";
|
|
$resqldelete = $db->query($sqldelete);
|
|
|
|
$res = $actionCommReminder->create($user);
|
|
|
|
if ($res <= 0) {
|
|
// If error
|
|
$langs->load("errors");
|
|
$error = $langs->trans('ErrorReminderActionCommCreation');
|
|
setEventMessages($error, null, 'errors');
|
|
$action = 'create';
|
|
$donotclearsession = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
unset($_SESSION[$sessionkeyassignedtouser]);
|
|
unset($_SESSION[$sessionkeyassignedtoresource]);
|
|
|
|
$db->commit();
|
|
} else {
|
|
$db->rollback();
|
|
$action = 'edit';
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$db->rollback();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
if (!empty($backtopage)) {
|
|
unset($_SESSION[$sessionkeyassignedtouser]);
|
|
header("Location: ".$backtopage);
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete event
|
|
if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes' && $usercandelete) {
|
|
$object->fetch($id);
|
|
$object->fetch_optionals();
|
|
$object->fetch_userassigned();
|
|
$object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
|
|
|
|
$result = $object->delete($user);
|
|
|
|
if ($result >= 0) {
|
|
header("Location: index.php");
|
|
exit;
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Action move update, used when user move an event in calendar by drag'n drop
|
|
* TODO Move this into page comm/action/index that trigger this call by the drag and drop of event.
|
|
*/
|
|
if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate' && $usercancreate) {
|
|
$error = 0;
|
|
|
|
$shour = (int) dol_print_date($object->datep, "%H", 'tzuserrel'); // We take the date visible by user $newdate is also date visible by user.
|
|
$smin = (int) dol_print_date($object->datep, "%M", 'tzuserrel');
|
|
|
|
$newdate = GETPOST('newdate', 'alpha');
|
|
if (empty($newdate) || strpos($newdate, 'dayevent_') != 0) {
|
|
header("Location: ".$backtopage, true, 307);
|
|
exit;
|
|
}
|
|
|
|
$datep = dol_mktime($shour, $smin, 0, (int) substr($newdate, 13, 2), (int) substr($newdate, 15, 2), (int) substr($newdate, 9, 4), 'tzuserrel');
|
|
//print dol_print_date($datep, 'dayhour');exit;
|
|
|
|
if ($datep != $object->datep) {
|
|
if (!empty($object->datef)) {
|
|
$object->datef += (int) $datep - $object->datep;
|
|
}
|
|
$object->datep = $datep;
|
|
|
|
if (!$error) {
|
|
// check if an event resource is already in use
|
|
if (getDolGlobalString('RESOURCE_USED_IN_EVENT_CHECK') && $object->element == 'action') {
|
|
$eventDateStart = $object->datep;
|
|
$eventDateEnd = $object->datef;
|
|
|
|
$sql = "SELECT er.rowid, r.ref as r_ref, ac.id as ac_id, ac.label as ac_label";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."element_resources as er";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."resource as r ON r.rowid = er.resource_id AND er.resource_type = 'dolresource'";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm as ac ON ac.id = er.element_id AND er.element_type = '".$db->escape($object->element)."'";
|
|
$sql .= " WHERE ac.id <> ".((int) $object->id);
|
|
$sql .= " AND er.resource_id IN (";
|
|
$sql .= " SELECT resource_id FROM ".MAIN_DB_PREFIX."element_resources";
|
|
$sql .= " WHERE element_id = ".((int) $object->id);
|
|
$sql .= " AND element_type = '".$db->escape($object->element)."'";
|
|
$sql .= " AND busy = 1";
|
|
$sql .= ")";
|
|
$sql .= " AND er.busy = 1";
|
|
$sql .= " AND (";
|
|
|
|
// event date start between ac.datep and ac.datep2 (if datep2 is null we consider there is no end)
|
|
$sql .= " (ac.datep <= '".$db->idate($eventDateStart)."' AND (ac.datep2 IS NULL OR ac.datep2 >= '".$db->idate($eventDateStart)."'))";
|
|
// event date end between ac.datep and ac.datep2
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " OR (ac.datep <= '".$db->idate($eventDateEnd)."' AND (ac.datep2 >= '".$db->idate($eventDateEnd)."'))";
|
|
}
|
|
// event date start before ac.datep and event date end after ac.datep2
|
|
$sql .= " OR (";
|
|
$sql .= "ac.datep >= '".$db->idate($eventDateStart)."'";
|
|
if (!empty($eventDateEnd)) {
|
|
$sql .= " AND (ac.datep2 IS NOT NULL AND ac.datep2 <= '".$db->idate($eventDateEnd)."')";
|
|
}
|
|
$sql .= ")";
|
|
|
|
$sql .= ")";
|
|
$resql = $db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$object->error = $db->lasterror();
|
|
$object->errors[] = $object->error;
|
|
} else {
|
|
if ($db->num_rows($resql) > 0) {
|
|
// Resource already in use
|
|
$error++;
|
|
$object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : ';
|
|
while ($obj = $db->fetch_object($resql)) {
|
|
$object->error .= '<br> - '.$langs->trans('ErrorResourceUseInEvent', $obj->r_ref, $obj->ac_label.' ['.$obj->ac_id.']');
|
|
}
|
|
$object->errors[] = $object->error;
|
|
}
|
|
$db->free($resql);
|
|
}
|
|
|
|
if ($error) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
$result = $object->update($user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$db->rollback();
|
|
} else {
|
|
$db->commit();
|
|
}
|
|
}
|
|
}
|
|
if (!empty($backtopage)) {
|
|
header("Location: ".$backtopage, true, 307);
|
|
exit;
|
|
} else {
|
|
$action = '';
|
|
}
|
|
}
|
|
|
|
// Actions to delete doc
|
|
$upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref);
|
|
$permissiontoadd = ($user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'read')));
|
|
if (empty($reshook)) {
|
|
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
|
|
}
|
|
|
|
|
|
/*
|
|
* View
|
|
*/
|
|
|
|
$form = new Form($db);
|
|
$formproject = new FormProjets($db);
|
|
|
|
$arrayrecurrulefreq = array(
|
|
'no' => $langs->trans("OnceOnly"),
|
|
'YEARLY' => $langs->trans("EveryYear"),
|
|
'MONTHLY' => $langs->trans("EveryMonth"),
|
|
'WEEKLY' => $langs->trans("EveryWeek")
|
|
// 'DAILY'=>$langs->trans("EveryDay")
|
|
);
|
|
|
|
|
|
$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda|DE:Modul_Terminplanung';
|
|
llxHeader('', $langs->trans("Agenda"), $help_url);
|
|
|
|
if ($action == 'create') {
|
|
$contact = new Contact($db);
|
|
|
|
$socpeopleassigned = GETPOST("socpeopleassigned", 'array');
|
|
if (!empty($socpeopleassigned[0])) {
|
|
$result = $contact->fetch($socpeopleassigned[0]);
|
|
if ($result < 0) {
|
|
dol_print_error($db, $contact->error);
|
|
}
|
|
}
|
|
|
|
dol_set_focus("#label");
|
|
|
|
if (!empty($conf->use_javascript_ajax)) {
|
|
print "\n".'<script type="text/javascript">';
|
|
print '$(document).ready(function () {
|
|
function setdatefields()
|
|
{
|
|
if ($("#fullday:checked").val() == null) {
|
|
$(".fulldaystarthour").removeAttr("disabled");
|
|
$(".fulldaystartmin").removeAttr("disabled");
|
|
$(".fulldayendhour").removeAttr("disabled");
|
|
$(".fulldayendmin").removeAttr("disabled");
|
|
$("#p2").removeAttr("disabled");
|
|
} else {
|
|
$(".fulldaystarthour").prop("disabled", true).val("00");
|
|
$(".fulldaystartmin").prop("disabled", true).val("00");
|
|
$(".fulldayendhour").prop("disabled", true).val("23");
|
|
$(".fulldayendmin").prop("disabled", true).val("59");
|
|
$("#p2").removeAttr("disabled");
|
|
}
|
|
}
|
|
$("#fullday").change(function() {
|
|
console.log("setdatefields");
|
|
setdatefields();
|
|
});
|
|
var old_startdate = null;
|
|
$("#ap").focus(function() {
|
|
old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
});
|
|
$("#ap").next(".ui-datepicker-trigger").click(function() {
|
|
old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
});
|
|
$("#ap").change(function() {
|
|
setTimeout(function() {
|
|
if ($("#p2").val() !== "") {
|
|
var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
|
|
if (new_startdate > old_enddate) {
|
|
var timeDiff = old_enddate - old_startdate;
|
|
var new_enddate = new Date(new_startdate.getTime() + timeDiff);
|
|
$("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
|
|
$("#p2day").val(new_enddate.getDate());
|
|
$("#p2month").val(new_enddate.getMonth() + 1);
|
|
$("#p2year").val(new_enddate.getFullYear());
|
|
}
|
|
}
|
|
}, 0);
|
|
});
|
|
$("#actioncode").change(function() {
|
|
if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
|
|
else $("#dateend").removeClass("fieldrequired");
|
|
});
|
|
$("#aphour,#apmin").change(function() {
|
|
if ($("#actioncode").val() == \'AC_RDV\') {
|
|
var oldhour = parseInt($("#aphour").val());
|
|
var oldmin = parseInt($("#apmin").val());
|
|
var oldday = parseInt($("#apday").val());
|
|
var oldmonth = $("#apmonth").val();
|
|
var oldyear = $("#apyear").val();
|
|
|
|
var newhour = oldhour + 1;
|
|
var newday = oldday;
|
|
var newmonth = oldmonth;
|
|
var newyear = oldyear;
|
|
if (newhour >= 24) {
|
|
newhour = 0;
|
|
newday = oldday + 1;
|
|
}
|
|
console.log("Start date was changed, we modify end date "+oldhour+" "+oldmin+" -> "+newhour+" "+oldmin);
|
|
$("#p2hour").val(("00" + newhour).substr(-2,2));
|
|
$("#p2min").val(("00" + oldmin).substr(-2,2));
|
|
$("#p2day").val(newday);
|
|
$("#p2month").val(newmonth);
|
|
$("#p2year").val(newyear);
|
|
$("#p2").val($("#ap").val());
|
|
}
|
|
});
|
|
if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
|
|
else $("#dateend").removeClass("fieldrequired");
|
|
setdatefields();
|
|
})';
|
|
print '</script>'."\n";
|
|
}
|
|
|
|
print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
|
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
|
print '<input type="hidden" name="action" value="add">';
|
|
print '<input type="hidden" name="donotclearsession" value="1">';
|
|
print '<input type="hidden" name="page_y" value="">';
|
|
if ($backtopage) {
|
|
print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
|
|
}
|
|
if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
|
|
print '<input type="hidden" name="actioncode" value="'.dol_getIdFromCode($db, 'AC_OTH', 'c_actioncomm').'">';
|
|
}
|
|
|
|
print load_fiche_titre($langs->trans("AddAnAction"), '', 'title_agenda');
|
|
|
|
print dol_get_fiche_head();
|
|
|
|
print '<div class="divcreate">';
|
|
print '<table class="border centpercent nobottom">';
|
|
|
|
// Title
|
|
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>';
|
|
|
|
// Type of event
|
|
if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
|
|
print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Type").'</span></b></td><td>';
|
|
$default = getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT', 'AC_OTH');
|
|
if (empty($default)) {
|
|
$default = 'AC_OTH';
|
|
}
|
|
print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
|
|
$selectedvalue = GETPOSTISSET("actioncode") ? GETPOST("actioncode", 'aZ09') : ($object->type_code ? $object->type_code : $default);
|
|
print $formactions->select_type_actions($selectedvalue, "actioncode", "systemauto", 0, -1, 0, 1); // TODO Replace 0 with -2 in onlyautoornot
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Full day
|
|
print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td>';
|
|
print '<td class="valignmiddle height30">';
|
|
print '<div>';
|
|
print '<input class="valignmiddle" type="checkbox" id="fullday" name="fullday" '.(GETPOST('fullday') ? ' checked' : '').'><label for="fullday" class="valignmiddle small">'.$langs->trans("EventOnFullDay").'</label>';
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
|
|
$datep = ($datep ? $datep : (is_null($object->datep) ? '' : $object->datep));
|
|
if (GETPOST('datep', 'alpha', 1)) {
|
|
$datep = dol_stringtotime(GETPOST('datep', 'alpha', 1), 'tzuserrel');
|
|
}
|
|
$datef = ($datef ? $datef : $object->datef);
|
|
if (GETPOST('datef', 'alpha', 1)) {
|
|
$datef = dol_stringtotime(GETPOST('datef', 'alpha', 1), 'tzuserrel');
|
|
}
|
|
if (empty($datef) && !empty($datep)) {
|
|
if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || (!getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') || getDolGlobalString('AGENDA_USE_EVENT_TYPE_DEFAULT') == '-1')) {
|
|
$datef = dol_time_plus_duree($datep, getDolGlobalInt('AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS', 1), 'h');
|
|
}
|
|
}
|
|
|
|
// Date start
|
|
print '<tr><td class="nowrap">';
|
|
print '</td><td>';
|
|
print '<div class="inline-block">';
|
|
if (GETPOST("afaire") == 1) {
|
|
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"
|
|
} else {
|
|
print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel');
|
|
}
|
|
print ' <span class="hideonsmartphone"> - </span><br class="showonsmartphone"> ';
|
|
print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel');
|
|
print '</div>';
|
|
|
|
//print '</td></tr>';
|
|
|
|
// Recurring event
|
|
$userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
|
|
if ($userepeatevent) {
|
|
//print '<tr><td></td><td>';
|
|
print '<div class="clearbothonsmartphone hideonsmartphone inline-block"> </div>';
|
|
|
|
// Repeat
|
|
print '<div class="inline-block small" data-html="repeat">';
|
|
print '<span class="opacitymedium">';
|
|
print img_picto($langs->trans("Recurrence"), 'recurring', 'style="margin-left: 3px" class="paddingright"');
|
|
print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
|
|
|
|
$selectedrecurrulefreq = 'no';
|
|
$selectedrecurrulebyyearmonthday = '';
|
|
$selectedrecurrulebymonthday = '';
|
|
$selectedrecurrulebyday = '';
|
|
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
|
|
$object->recurrule .= GETPOSTISSET('BYYEARMONTHDAY') ? "_BYYEARMONTHDAY".GETPOST('BYYEARMONTHDAY', 'alpha') : "";
|
|
$object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
|
|
$object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
|
|
|
|
|
|
$reg = [];
|
|
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
|
|
$selectedrecurrulefreq = $reg[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
|
|
$selectedrecurrulebyyearmonthday = (int) $reg[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
|
|
$selectedrecurrulebymonthday = (int) $reg[1];
|
|
}
|
|
if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
|
|
$selectedrecurrulebyday = (int) $reg[1];
|
|
}
|
|
|
|
print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly minwidth125 maxwidth150');
|
|
print '</span>';
|
|
// print '<script>console.log("recurrule: " +'.$object->recurrule.')</script>';
|
|
// For recursive event
|
|
|
|
|
|
// If recurrulefreq is MONTHLY
|
|
/*
|
|
print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
|
|
print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
|
|
print '</div>';
|
|
// If recurrulefreq is WEEKLY
|
|
print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
|
|
print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
|
|
print '</div>';
|
|
*/
|
|
|
|
// limit date
|
|
$repeateventlimitdate = empty($repeateventlimitdate) ? (dol_now() + ((24 * 3600 * 365) + 1)) : $repeateventlimitdate;
|
|
|
|
print '<div class="hidden marginrightonly inline-block repeateventlimitdate">';
|
|
print $langs->trans("Until")." ";
|
|
print $form->selectDate($repeateventlimitdate, 'limit', 0, 0, 0, "action", 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
|
|
print '</div>';
|
|
?>
|
|
<script type="text/javascript">
|
|
jQuery(document).ready(function() {
|
|
function init_repeat() {
|
|
console.log("recurrule: " + "<?php echo $object->recurrule; ?>");
|
|
console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>");
|
|
console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>");
|
|
console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>");
|
|
console.log("reg4: " + "<?php echo $selectedrecurrulebyyearmonthday; ?>");
|
|
console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>");
|
|
if (jQuery("#recurrulefreq").val() == 'YEARLY') {
|
|
/* jQuery(".repeateventBYYEARMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
|
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
|
jQuery(".repeateventBYMONTHDAY").hide();
|
|
jQuery(".repeateventBYDAY").hide();
|
|
} else if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
|
|
/* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
|
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
|
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
|
jQuery(".repeateventBYDAY").hide();
|
|
} else if (jQuery("#recurrulefreq").val() == 'WEEKLY') {
|
|
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
|
jQuery(".repeateventBYMONTHDAY").hide();
|
|
/* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
|
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
|
} else {
|
|
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
|
jQuery(".repeateventBYMONTHDAY").hide();
|
|
jQuery(".repeateventBYDAY").hide();
|
|
jQuery(".repeateventlimitdate").hide();
|
|
}
|
|
}
|
|
init_repeat();
|
|
jQuery("#recurrulefreq").change(function() {
|
|
init_repeat();
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
print '</div>';
|
|
// print '</td></tr>';
|
|
}
|
|
|
|
print '</td></tr>';
|
|
|
|
|
|
// Location
|
|
if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Location").'</td><td>';
|
|
print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
|
|
print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.(GETPOST('location') ? GETPOST('location') : $object->location).'"></td></tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
print '<br>';
|
|
|
|
print '<div class="divcreate">';
|
|
print '<table class="border centpercent nobottom">';
|
|
|
|
// Assigned to user
|
|
print '<tr><td class="nowrap titlefieldcreate"><span>';
|
|
print $langs->trans("AssignedTo");
|
|
print '</span></td><td>';
|
|
$listofuserid = [];
|
|
$listofcontactid = [];
|
|
$listofotherid = [];
|
|
|
|
if (empty($donotclearsession)) {
|
|
$assignedtouser = GETPOST("assignedtouser") ? GETPOST("assignedtouser") : (!empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : $user->id);
|
|
if ($assignedtouser) {
|
|
$listofuserid[$assignedtouser] = array('id' => $assignedtouser, 'mandatory' => 0); // Owner first
|
|
}
|
|
//$listofuserid[$user->id] = array('id'=>$user->id, 'mandatory'=>0, 'transparency'=>(GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1)); // 1 by default at first init
|
|
$listofuserid[$assignedtouser]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 1); // 1 by default at first init
|
|
$_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
|
|
} else {
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
}
|
|
if (!is_array($listofuserid)) {
|
|
$listofuserid = [];
|
|
}
|
|
$firstelem = reset($listofuserid);
|
|
if (isset($listofuserid[$firstelem['id']])) {
|
|
$listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
|
|
}
|
|
}
|
|
print '<!-- list of user to assign -->'."\n";
|
|
print '<div class="assignedtouser">';
|
|
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid);
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
|
|
if (isModEnabled('resource')) {
|
|
// Resources
|
|
print '<tr><td class="tdtop nowrap">'.$langs->trans("Resource").'</td><td>';
|
|
|
|
$listofresourceid = [];
|
|
if (empty($donotclearsession)) {
|
|
$assignedtoresource = GETPOST("assignedtoresource");
|
|
if ($assignedtoresource) {
|
|
$listofresourceid[$assignedtoresource] = array('id' => $assignedtoresource, 'mandatory' => 0); // Owner first
|
|
}
|
|
$_SESSION[$sessionkeyassignedtoresource] = json_encode($listofresourceid);
|
|
} else {
|
|
if (!empty($_SESSION[$sessionkeyassignedtoresource])) {
|
|
$listofresourceid = json_decode($_SESSION[$sessionkeyassignedtoresource], true);
|
|
}
|
|
if (!is_array($listofresourceid)) {
|
|
$listofresourceid = [];
|
|
}
|
|
$firstelem = reset($listofresourceid);
|
|
if ($firstelem && isset($listofresourceid[$firstelem['id']])) {
|
|
$listofresourceid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
|
|
}
|
|
}
|
|
print '<div class="assignedtoresource">';
|
|
print $form->select_dolresources_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtoresource', 1, [], 0, '', [], '0', 0, 0, 'AND u.statut != 0', 1, $listofresourceid);
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
}
|
|
|
|
if (isModEnabled('category')) {
|
|
// Categories
|
|
print '<tr><td>'.$langs->trans("Categories").'</td><td>';
|
|
print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
|
|
print "</td></tr>";
|
|
}
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
|
|
print '<br>';
|
|
|
|
print '<div class="divcreate">';
|
|
print '<table class="border centpercent nobottom">';
|
|
|
|
// Status
|
|
print '<tr><td>'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td>';
|
|
print '<td>';
|
|
$percent = $complete !== '' ? $complete : -1;
|
|
if (GETPOSTISSET('status')) {
|
|
$percent = GETPOST('status');
|
|
} elseif (GETPOSTISSET('percentage')) {
|
|
$percent = GETPOSTINT('percentage');
|
|
} else {
|
|
if ($complete == '0' || GETPOST("afaire") == 1) {
|
|
$percent = '0';
|
|
} elseif ($complete == 100 || GETPOST("afaire") == 2) {
|
|
$percent = 100;
|
|
}
|
|
}
|
|
print $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300', 1);
|
|
print '</td></tr>';
|
|
|
|
if (isModEnabled("societe")) {
|
|
// Related company
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ActionOnCompany").'</td><td>';
|
|
if (GETPOSTINT('socid') > 0) {
|
|
$societe = new Societe($db);
|
|
$societe->fetch(GETPOSTINT('socid'));
|
|
print $societe->getNomUrl(1);
|
|
print '<input type="hidden" id="socid" name="socid" value="'.GETPOSTINT('socid').'">';
|
|
} else {
|
|
$events = [];
|
|
$events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
|
|
//For external user force the company to user company
|
|
if (!empty($user->socid)) {
|
|
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($user->socid, 'socid', '', 1, 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
|
|
} else {
|
|
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '', $langs->trans('SelectThirdParty'), 1, 0, $events, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
|
|
}
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// Related contact
|
|
print '<tr><td class="nowrap">'.$langs->trans("ActionOnContact").'</td><td>';
|
|
$preselectedids = GETPOST('socpeopleassigned', 'array:int');
|
|
if (GETPOSTINT('contactid')) {
|
|
$preselectedids[GETPOSTINT('contactid')] = GETPOSTINT('contactid');
|
|
}
|
|
if ($origin == 'contact') {
|
|
$preselectedids[GETPOSTINT('originid')] = GETPOSTINT('originid');
|
|
}
|
|
// select "all" or "none" contact by default
|
|
if (getDolGlobalInt('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT')) {
|
|
// Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
|
|
$select_contact_default = 0; // select "all" contacts by default : avoid to use it if there is a lot of contacts
|
|
} else {
|
|
$select_contact_default = -1; // select "none" by default
|
|
}
|
|
print img_picto('', 'contact', 'class="pictofixedwidth"');
|
|
|
|
if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
|
|
// 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...
|
|
/*
|
|
$selected = array_keys($object->socpeopleassigned);
|
|
print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
|
|
*/
|
|
$sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
|
|
$conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
|
|
print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
|
|
$conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
|
|
} else {
|
|
print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 widthcentpercentminusxx maxwidth500', 0, 0, 0, [], 'multiple', 'contactid');
|
|
}
|
|
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Project
|
|
if (isModEnabled('project')) {
|
|
$langs->load("projects");
|
|
|
|
$projectid = GETPOSTINT('projectid');
|
|
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td id="project-input-container">';
|
|
print img_picto('', 'project', 'class="pictofixedwidth"');
|
|
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');
|
|
|
|
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(empty($societe->id) ? '' : $societe->id).'&action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">';
|
|
print '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>';
|
|
$urloption = '?action=create&donotclearsession=1';
|
|
$url = dol_buildpath('comm/action/card.php', 2).$urloption;
|
|
|
|
// update task list
|
|
?>
|
|
<script type="text/javascript">
|
|
$(document).ready(function () {
|
|
$("#projectid").change(function () {
|
|
var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
|
|
console.log("Call url to get the new list of tasks: "+url);
|
|
$.get(url, function(data) {
|
|
console.log(data);
|
|
if (data) $("#taskid").html(data).select2();
|
|
})
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
print '</td></tr>';
|
|
|
|
// Task
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Task").'</td><td id="project-task-input-container" >';
|
|
print img_picto('', 'projecttask', 'class="pictofixedwidth"');
|
|
$projectsListId = '';
|
|
if (!empty($projectid)) {
|
|
$projectsListId = $projectid;
|
|
}
|
|
|
|
$tid = GETPOSTISSET("projecttaskid") ? GETPOSTINT("projecttaskid") : (GETPOSTISSET("taskid") ? GETPOSTINT("taskid") : '');
|
|
|
|
if (empty($projectsListId)) {
|
|
print '<select class="valignmiddle flat maxwidth500 widthcentpercentminusxx minwidth150imp" id="taskid" name="taskid">';
|
|
print '<option class="opacitymedium"> </option>';
|
|
print '<option class="opacitymedium" disabled data-html="'.dolPrintHTMLForAttribute($langs->trans("SelectAProjectFirst")).'">'.$langs->trans("SelectAProjectFirst").'</option>';
|
|
print '</select>';
|
|
print ajax_combobox('taskid');
|
|
} else {
|
|
print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Object linked
|
|
if (!empty($origin) && !empty($originid)) {
|
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
|
|
|
$hasPermissionOnLinkedObject = 0;
|
|
|
|
$elProp = getElementProperties($origin);
|
|
$modulecodetouseforpermissioncheck = $elProp['module'];
|
|
// Keep permission check aligned with rights class aliases (see restrictedArea()).
|
|
$submodulecodetouseforpermissioncheck = $elProp['subelement'];
|
|
|
|
switch ($modulecodetouseforpermissioncheck) {
|
|
case 'productbatch':
|
|
$modulecodetouseforpermissioncheck = 'produit';
|
|
break;
|
|
case 'eventorganization':
|
|
// Event organization relies on Project permissions
|
|
$modulecodetouseforpermissioncheck = 'projet';
|
|
$submodulecodetouseforpermissioncheck = ''; // Project doesn't use submodules for read
|
|
break;
|
|
default:
|
|
// No mapping needed, keep original values
|
|
break;
|
|
}
|
|
|
|
if ($user->hasRight($modulecodetouseforpermissioncheck, 'read') || $user->hasRight($modulecodetouseforpermissioncheck, $elProp['element'], 'read')) {
|
|
$hasPermissionOnLinkedObject = 1;
|
|
}
|
|
//var_dump('origin='.$origin.' originid='.$originid.' hasPermissionOnLinkedObject='.$hasPermissionOnLinkedObject);
|
|
|
|
if (! in_array($origin, array('societe', 'project', 'project_task', 'user'))) {
|
|
// We do not use link for object that already contains a hard coded field to make links with agenda events
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("LinkedObject").'</td>';
|
|
print '<td colspan="3">';
|
|
if ($hasPermissionOnLinkedObject) {
|
|
print dolGetElementUrl($originid, $origin, 1);
|
|
print '<input type="hidden" name="fk_element" value="'.$originid.'">';
|
|
print '<input type="hidden" name="elementtype" value="'.$origin.'">';
|
|
print '<input type="hidden" name="originid" value="'.$originid.'">';
|
|
print '<input type="hidden" name="origin" value="'.$origin.'">';
|
|
} else {
|
|
print '<!-- no permission on object to link '.$origin.' id '.$originid.' -->';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
}
|
|
|
|
// Priority
|
|
if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td colspan="3">';
|
|
print '<input type="text" name="priority" value="'.(GETPOSTISSET('priority') ? GETPOSTINT('priority') : ($object->priority ? $object->priority : '')).'" size="5">';
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Description
|
|
print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
|
$doleditor = new DolEditor('note', (GETPOSTISSET('note') ? GETPOST('note', 'restricthtml') : $object->note_private), '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
|
|
$doleditor->Create();
|
|
print '</td></tr>';
|
|
|
|
// Other attributes
|
|
$parameters = [];
|
|
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
if (empty($reshook)) {
|
|
print $object->showOptionals($extrafields, 'create', $parameters);
|
|
}
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
if ($enablereminders) {
|
|
//checkbox create reminder
|
|
print '<hr>';
|
|
|
|
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>';
|
|
|
|
print '<div class="reminderparameters" '.(empty(GETPOST('addreminder')) ? 'style="display: none;' : '').' ">';
|
|
print '<br>';
|
|
|
|
print '<table class="border centpercent">';
|
|
|
|
//Reminder
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
|
|
print '<input class="width50" type="number" name="offsetvalue" value="'.(GETPOSTISSET('offsetvalue') ? GETPOSTINT('offsetvalue') : getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30)).'"> ';
|
|
|
|
print $form->selectTypeDuration('offsetunit', (empty($offsetunit) ? 'i' : $offsetunit), $TDurationTypesExcluded);
|
|
print '</td></tr>';
|
|
|
|
//Reminder Type
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
|
|
print $form->selectarray('selectremindertype', $TRemindTypes, '', 0, 0, 0, '', 0, 0, 0, '', 'minwidth200 maxwidth500', 1);
|
|
print '</td></tr>';
|
|
|
|
//Mail Model
|
|
if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
|
|
print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (empty($modelmail) ? 0 : $modelmail));
|
|
print '</td></tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
$reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
|
|
$reminderDefaultOffset = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
|
|
$reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
|
|
$reminderDefaultEmailModel = getDolGlobalInt('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
|
|
|
|
print "\n".'<script type="text/javascript">';
|
|
print '$(document).ready(function () {
|
|
const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
|
|
$("#actioncode").change(function(){
|
|
var selected_event_type = $("#actioncode option:selected").val();
|
|
|
|
if (reminderDefaultEventTypes.includes(selected_event_type)) {
|
|
$(".reminderparameters").show();
|
|
$("#addreminder").prop("checked", true);
|
|
|
|
// Set period with default reminder period
|
|
$("[name=\"offsetvalue\"]").val(\'' . dol_escape_js((string) $reminderDefaultOffset) . '\');
|
|
$("#select_offsetunittype_duration").select2("destroy");
|
|
$("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
|
|
$("#select_offsetunittype_duration").select2();
|
|
|
|
$("#selectremindertype").select2("destroy");
|
|
$("#selectremindertype").val("email");
|
|
$("#selectremindertype").select2();
|
|
|
|
// Set default reminder mail model
|
|
$("#select_actioncommsendmodel_mail").closest("tr").show();
|
|
$("#select_actioncommsendmodel_mail").select2("destroy");
|
|
$("#select_actioncommsendmodel_mail").val(\''.dol_escape_js((string) $reminderDefaultEmailModel).'\');
|
|
$("#select_actioncommsendmodel_mail").select2();
|
|
}
|
|
});
|
|
})';
|
|
print '</script>'."\n";
|
|
|
|
print "\n".'<script type="text/javascript">';
|
|
print '$(document).ready(function () {
|
|
function toggle_reminder_part(evt) {
|
|
console.log("Toggle reminder part");
|
|
if ($("#addreminder").is(":checked")) {
|
|
$(".reminderparameters").show();
|
|
} else {
|
|
$(".reminderparameters").hide();
|
|
}
|
|
$("#selectremindertype").select2("destroy");
|
|
$("#selectremindertype").select2();
|
|
$("#select_offsetunittype_duration").select2("destroy");
|
|
$("#select_offsetunittype_duration").select2();
|
|
selectremindertype();
|
|
}
|
|
|
|
toggle_reminder_part();
|
|
$("#addreminder").click(toggle_reminder_part);
|
|
|
|
$("#selectremindertype").change(function(){
|
|
selectremindertype();
|
|
});
|
|
|
|
function selectremindertype() {
|
|
console.log("Call selectremindertype");
|
|
var selected_option = $("#selectremindertype option:selected").val();
|
|
if(selected_option == "email") {
|
|
$("#select_actioncommsendmodel_mail").closest("tr").show();
|
|
} else {
|
|
$("#select_actioncommsendmodel_mail").closest("tr").hide();
|
|
}
|
|
}
|
|
|
|
})';
|
|
print '</script>'."\n";
|
|
}
|
|
|
|
print dol_get_fiche_end();
|
|
|
|
print $form->buttonsSaveCancel("Create");
|
|
|
|
print "</form>";
|
|
}
|
|
|
|
// View or edit
|
|
if ($id > 0 && $action != 'create') {
|
|
$result1 = $object->fetch($id);
|
|
if ($result1 <= 0) {
|
|
recordNotFound('', 0);
|
|
}
|
|
|
|
$result2 = $object->fetch_thirdparty();
|
|
$result2 = $object->fetchProject();
|
|
$result3 = $object->fetch_contact();
|
|
$result4 = $object->fetch_userassigned();
|
|
$result5 = $object->fetch_optionals();
|
|
|
|
if ($listUserAssignedUpdated || $donotclearsession) {
|
|
$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
|
|
|
|
$datep = dol_mktime($fulldayevent ? 0 : $aphour, $fulldayevent ? 0 : $apmin, 0, GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), 'tzuserrel');
|
|
$datef = dol_mktime($fulldayevent ? 23 : $p2hour, $fulldayevent ? 59 : $p2min, $fulldayevent ? 59 : 0, GETPOSTINT("p2month"), GETPOSTINT("p2day"), GETPOSTINT("p2year"), 'tzuserrel');
|
|
|
|
$object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm');
|
|
$object->label = GETPOST("label", "alphanohtml");
|
|
$object->datep = $datep;
|
|
$object->datef = $datef;
|
|
$object->percentage = $percentage;
|
|
$object->priority = GETPOSTINT("priority");
|
|
$object->fulldayevent = GETPOST("fullday") ? 1 : 0;
|
|
$object->location = GETPOST('location', "alphanohtml");
|
|
$object->socid = GETPOSTINT("socid");
|
|
$socpeopleassigned = GETPOST("socpeopleassigned", 'array');
|
|
foreach ($socpeopleassigned as $tmpid) {
|
|
$object->socpeopleassigned[$id] = array('id' => $tmpid);
|
|
}
|
|
$object->contact_id = GETPOSTINT("contactid");
|
|
$object->fk_project = GETPOSTINT("projectid");
|
|
|
|
$object->note_private = GETPOST("note", 'restricthtml');
|
|
}
|
|
|
|
if ($result2 < 0 || $result3 < 0 || $result4 < 0 || $result5 < 0) {
|
|
dol_print_error($db, $object->error);
|
|
exit;
|
|
}
|
|
|
|
|
|
/*
|
|
* Show tabs
|
|
*/
|
|
|
|
$head = actions_prepare_head($object);
|
|
|
|
$now = dol_now();
|
|
$delay_warning = getDolGlobalInt('MAIN_DELAY_ACTIONS_TODO') * 24 * 60 * 60;
|
|
|
|
|
|
// Deletion confirmation action
|
|
if ($action == 'delete') {
|
|
print $form->formconfirm("card.php?id=".urlencode((string) ($id)), $langs->trans("DeleteAction"), $langs->trans("ConfirmDeleteAction"), "confirm_delete", '', '', 1);
|
|
}
|
|
|
|
if ($action == 'edit') {
|
|
$caneditdateorowner = ($object->type != 'systemauto');
|
|
|
|
if (!empty($conf->use_javascript_ajax)) {
|
|
print "\n".'<script type="text/javascript">';
|
|
print '$(document).ready(function () {
|
|
function setdatefields()
|
|
{
|
|
if ($("#fullday:checked").val() == null) {
|
|
$(".fulldaystarthour").removeAttr("disabled");
|
|
$(".fulldaystartmin").removeAttr("disabled");
|
|
$(".fulldayendhour").removeAttr("disabled");
|
|
$(".fulldayendmin").removeAttr("disabled");
|
|
} else {
|
|
$(".fulldaystarthour").prop("disabled", true).val("00");
|
|
$(".fulldaystartmin").prop("disabled", true).val("00");
|
|
$(".fulldayendhour").prop("disabled", true).val("23");
|
|
$(".fulldayendmin").prop("disabled", true).val("59");
|
|
}
|
|
}
|
|
|
|
'.($caneditdateorowner ? ' setdatefields();' : '').'
|
|
|
|
$("#fullday").change(function() {
|
|
setdatefields();
|
|
});
|
|
var old_startdate = null;
|
|
$("#ap").focus(function() {
|
|
old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
});
|
|
$("#ap").next(".ui-datepicker-trigger").click(function() {
|
|
old_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
});
|
|
$("#ap").change(function() {
|
|
setTimeout(function() {
|
|
if ($("#p2").val() !== "") {
|
|
var new_startdate = new Date($("#apyear").val(), $("#apmonth").val() - 1, $("#apday").val());
|
|
var old_enddate = new Date($("#p2year").val(), $("#p2month").val() - 1, $("#p2day").val());
|
|
if (new_startdate > old_enddate) {
|
|
var timeDiff = old_enddate - old_startdate;
|
|
var new_enddate = new Date(new_startdate.getTime() + timeDiff);
|
|
$("#p2").val(formatDate(new_enddate, "' . $langs->trans('FormatDateShortJavaInput') . '"));
|
|
$("#p2day").val(new_enddate.getDate());
|
|
$("#p2month").val(new_enddate.getMonth() + 1);
|
|
$("#p2year").val(new_enddate.getFullYear());
|
|
}
|
|
}
|
|
}, 0);
|
|
});
|
|
$("#actioncode").change(function() {
|
|
if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
|
|
else $("#dateend").removeClass("fieldrequired");
|
|
});
|
|
})';
|
|
print '</script>'."\n";
|
|
}
|
|
|
|
print '<form name="formaction" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
|
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
|
print '<input type="hidden" name="action" value="update">';
|
|
print '<input type="hidden" name="id" value="'.$id.'">';
|
|
print '<input type="hidden" name="ref_ext" value="'.$object->ref_ext.'">';
|
|
print '<input type="hidden" name="page_y" value="">';
|
|
if ($backtopage) {
|
|
print '<input type="hidden" name="backtopage" value="'.($backtopage != '1' ? $backtopage : '').'">';
|
|
}
|
|
if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE') && ! preg_match('/^TICKET_MSG_PRIVATE/', $object->code)) {
|
|
print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
|
|
}
|
|
|
|
print dol_get_fiche_head($head, 'card', $langs->trans("Action"), 0, 'action');
|
|
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
// Ref
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>'.$object->id.'</td></tr>';
|
|
|
|
// Title
|
|
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>';
|
|
|
|
// Type of event
|
|
if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && $object->elementtype != "ticket") {
|
|
print '<tr><td class="fieldrequired">'.$langs->trans("Type").'</td><td>';
|
|
if ($object->type_code != 'AC_OTH_AUTO') {
|
|
print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"');
|
|
print $formactions->select_type_actions(GETPOST("actioncode", 'aZ09') ? GETPOST("actioncode", 'aZ09') : $object->type_code, "actioncode", "systemauto", 0, 0, 0, 1);
|
|
} else {
|
|
print '<input type="hidden" name="actioncode" value="'.$object->type_code.'">';
|
|
print $object->getTypePicto();
|
|
print $langs->trans("Action".$object->type_code);
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Private
|
|
if ($object->elementtype == 'ticket') {
|
|
print '<tr><td>'.$langs->trans("MarkMessageAsPrivate");
|
|
print ' '.$form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help');
|
|
print '</td><td><input type="checkbox" id="private" name="private" '.(preg_match('/^TICKET_MSG_PRIVATE/', $object->code) ? ' checked' : '').'></td></tr>';
|
|
}
|
|
|
|
// Full day event
|
|
print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td class="valignmiddle height30 small">';
|
|
print '<input '.($caneditdateorowner ? '' : ' disabled').' type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
|
|
print '<label for="fullday">'.$langs->trans("EventOnFullDay").'</label>';
|
|
|
|
// // Recurring event
|
|
// $userepeatevent = (getDolGlobalInt('MAIN_DISABLE_RECURRING_EVENTS') ? 0 : 1);
|
|
// if ($userepeatevent) {
|
|
// // Repeat
|
|
// //print '<tr><td></td><td colspan="3">';
|
|
// print ' <div class="opacitymedium inline-block">';
|
|
// print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
|
|
// print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
|
|
// $selectedrecurrulefreq = 'no';
|
|
// $selectedrecurrulebymonthday = '';
|
|
// $selectedrecurrulebyday = '';
|
|
// if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
|
|
// $selectedrecurrulefreq = $reg[1];
|
|
// }
|
|
// if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
|
|
// $selectedrecurrulebymonthday = $reg[1];
|
|
// }
|
|
// if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
|
|
// $selectedrecurrulebyday = $reg[1];
|
|
// }
|
|
// print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
|
|
// // If recurrulefreq is MONTHLY
|
|
// print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
|
|
// print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
|
|
// print '</div>';
|
|
// // If recurrulefreq is WEEKLY
|
|
// print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
|
|
// print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
|
|
// print '</div>';
|
|
// print '<script type="text/javascript">
|
|
// jQuery(document).ready(function() {
|
|
// function init_repeat()
|
|
// {
|
|
// if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
|
|
// {
|
|
// jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
|
|
// jQuery(".repeateventBYDAY").hide();
|
|
// }
|
|
// else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
|
|
// {
|
|
// jQuery(".repeateventBYMONTHDAY").hide();
|
|
// jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
|
|
// }
|
|
// else
|
|
// {
|
|
// jQuery(".repeateventBYMONTHDAY").hide();
|
|
// jQuery(".repeateventBYDAY").hide();
|
|
// }
|
|
// }
|
|
// init_repeat();
|
|
// jQuery("#recurrulefreq").change(function() {
|
|
// init_repeat();
|
|
// });
|
|
// });
|
|
// </script>';
|
|
// print '</div>';
|
|
// //print '</td></tr>';
|
|
// }
|
|
print '</td></tr>';
|
|
|
|
// Date start - end
|
|
print '<tr><td class="nowrap">';
|
|
print '</td><td>';
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
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');
|
|
print ' <span class="hideonsmartphone"> - </span> ';
|
|
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');
|
|
print '</td></tr>';
|
|
|
|
// Location
|
|
if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
|
|
print '<tr><td>'.$langs->trans("Location").'</td><td>';
|
|
print img_picto('', 'map-marker-alt', 'class="pictofixedwidth"');
|
|
print '<input type="text" name="location" class="minwidth300 maxwidth150onsmartphone" value="'.$object->location.'"></td></tr>';
|
|
}
|
|
|
|
print '<tr class="tdsmallheight"><td class="tdsmallheight"> </td><td class="tdsmallheight"></td></tr>';
|
|
|
|
// Assigned to
|
|
$listofuserid = []; // User assigned
|
|
if (empty($donotclearsession)) {
|
|
if ($object->userownerid > 0) {
|
|
$listofuserid[$object->userownerid] = array(
|
|
'id' => $object->userownerid,
|
|
'type' => 'user',
|
|
//'transparency'=>$object->userassigned[$user->id]['transparency'],
|
|
'transparency' => $object->transparency, // Force transparency on ownerfrom event
|
|
'answer_status' => (isset($object->userassigned[$object->userownerid]['answer_status']) ? $object->userassigned[$object->userownerid]['answer_status'] : null),
|
|
'mandatory' => (isset($object->userassigned[$object->userownerid]['mandatory']) ? $object->userassigned[$object->userownerid]['mandatory'] : null)
|
|
);
|
|
}
|
|
if (!empty($object->userassigned)) { // Now concat assigned users
|
|
// Restore array with key with same value than param 'id'
|
|
$tmplist1 = $object->userassigned;
|
|
foreach ($tmplist1 as $key => $val) {
|
|
if ($val['id'] && $val['id'] != $object->userownerid) {
|
|
$listofuserid[$val['id']] = $val;
|
|
}
|
|
}
|
|
}
|
|
$_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
|
|
} else {
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
}
|
|
}
|
|
|
|
$listofcontactid = $object->socpeopleassigned; // Contact assigned
|
|
$listofotherid = $object->otherassigned; // Other undefined email (not used yet)
|
|
|
|
print '<tr><td class="nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
|
|
print '<div class="assignedtouser">';
|
|
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner);
|
|
print '</div>';
|
|
/*if (in_array($user->id,array_keys($listofuserid)))
|
|
{
|
|
print '<div class="myavailability">';
|
|
print $langs->trans("MyAvailability").': <input id="transparency" type="checkbox" name="transparency"'.($listofuserid[$user->id]['transparency']?' checked':'').'>'.$langs->trans("Busy");
|
|
print '</div>';
|
|
}*/
|
|
print '</td></tr>';
|
|
|
|
// Tags-Categories
|
|
if (isModEnabled('category')) {
|
|
print '<tr><td>'.$langs->trans("Categories").'</td><td>';
|
|
print $form->selectCategories(Categorie::TYPE_ACTIONCOMM, 'categories', $object);
|
|
print "</td></tr>";
|
|
}
|
|
|
|
print '</table>';
|
|
|
|
|
|
print '<br>';
|
|
|
|
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
// Status
|
|
print '<tr><td class="nowrap">'.$langs->trans("Status").' / '.$langs->trans("Progression").'</td><td colspan="3">';
|
|
$percent = GETPOSTISSET("percentage") ? GETPOSTINT("percentage") : $object->percentage;
|
|
$formactions->form_select_status_action('formaction', (string) $percent, 1, 'complete', 0, 0, 'minwidth150 maxwidth300');
|
|
print '</td></tr>';
|
|
|
|
if (isModEnabled("societe")) {
|
|
// Related company
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("ActionOnCompany").'</td>';
|
|
print '<td>';
|
|
print '<div>';
|
|
$events = []; // 'method'=parameter action of url, 'url'=url to call that return new list of contacts
|
|
$events[] = array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1&token='.currentToken(), 1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled'));
|
|
// TODO Refresh also list of project if conf PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY not defined with list linked to socid ?
|
|
// FIXME If we change company, we may get a project that does not match
|
|
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($object->socid, 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300');
|
|
print '</div>';
|
|
print '</td></tr>';
|
|
|
|
// Related contact
|
|
print '<tr><td>'.$langs->trans("ActionOnContact").'</td><td>';
|
|
print '<div class="maxwidth200onsmartphone">';
|
|
|
|
print img_picto('', 'contact', 'class="paddingrightonly"');
|
|
if (getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT') && $conf->use_javascript_ajax) {
|
|
// FIXME Use the select_contact supporting the "multiple"
|
|
/*
|
|
$selected = array_keys($object->socpeopleassigned);
|
|
print $form->select_contact(getDolGlobalString('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT') ? 0 : $object->socid, $selected, 'socpeopleassigned', 1, '', '', 1, 'minwidth300 widthcentpercentminusx', false, 0, 0, []);
|
|
*/
|
|
$sav = getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT');
|
|
$conf->global->CONTACT_USE_SEARCH_TO_SELECT = 0;
|
|
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');
|
|
$conf->global->CONTACT_USE_SEARCH_TO_SELECT = $sav;
|
|
} else {
|
|
// Warning: MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT will hangs on large databases
|
|
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');
|
|
}
|
|
print '</div>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Project
|
|
if (isModEnabled('project')) {
|
|
$langs->load("projects");
|
|
|
|
print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td>';
|
|
print img_picto('', 'project', 'class="pictofixedwidth"');
|
|
$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');
|
|
if ($numprojet == 0) {
|
|
print ' <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>';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Priority
|
|
if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td>';
|
|
print '<input type="text" name="priority" value="'.($object->priority ? $object->priority : '').'" size="5">';
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Object linked
|
|
if ($object->fk_project || (!empty($object->elementid) && !empty($object->elementtype))) {
|
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
|
print '<tr>';
|
|
print '<td>'.$langs->trans("LinkedObject").'</td>';
|
|
|
|
if ($object->elementtype == 'project_task' && isModEnabled('project')) {
|
|
print '<td id="project-task-input-container" >';
|
|
|
|
$urloption = '?action=create&donotclearsession=1'; // we use create not edit for more flexibility
|
|
$url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption;
|
|
|
|
// update task list
|
|
?>
|
|
<script type="text/javascript" >
|
|
$(document).ready(function () {
|
|
$("#projectid").change(function () {
|
|
var url = "<?php echo $url; ?>&projectid="+$("#projectid").val();
|
|
$.get(url, function(data) {
|
|
console.log($( data ).find("#fk_element").html());
|
|
if (data) $("#fk_element").html( $( data ).find("#taskid").html() ).select2();
|
|
})
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
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);
|
|
print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
|
|
|
|
print '</td>';
|
|
} else {
|
|
if (empty($object->elementtype) && empty($object->elementid) && $object->fk_project) {
|
|
$projectsListId = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : $object->fk_project;
|
|
|
|
print '<td id="project-task-input-container" >';
|
|
|
|
// update task list
|
|
?>
|
|
<script type="text/javascript">
|
|
$(document).ready(function () {
|
|
$("#projectid").change(function () {
|
|
var url = "<?php echo DOL_URL_ROOT; ?>/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
|
|
console.log("Call url to get new list of tasks: "+url);
|
|
$.get(url, function(data) {
|
|
console.log(data);
|
|
if (data) $("#taskid").html(data).select2();
|
|
})
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
$tid = '';
|
|
if (GETPOSTISSET("projecttaskid") && GETPOSTINT("projecttaskid") > 0) {
|
|
$tid = GETPOSTINT("projecttaskid");
|
|
} elseif (GETPOSTISSET("taskid") && GETPOSTINT("taskid") > 0) {
|
|
$tid = GETPOSTINT("taskid");
|
|
}
|
|
|
|
print $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 64, 0, '1', 1, 0, 0, 'maxwidth500 widthcentpercentminusxx', (string) $projectsListId, 'all', null, 1);
|
|
|
|
print '</td>';
|
|
} else {
|
|
print '<td>';
|
|
print dolGetElementUrl($object->elementid, $object->elementtype, 1);
|
|
print '<input type="hidden" name="fk_element" value="'.$object->elementid.'">';
|
|
print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
|
|
print '</td>';
|
|
}
|
|
}
|
|
|
|
print '</tr>';
|
|
}
|
|
|
|
// Description
|
|
print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
|
|
// Wysiwyg editor
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
|
$doleditor = new DolEditor('note', $object->note_private, '', 200, 'dolibarr_notes', 'In', true, true, isModEnabled('fckeditor'), ROWS_4, '90%');
|
|
$doleditor->Create();
|
|
print '</td></tr>';
|
|
|
|
// Other attributes
|
|
$parameters = [];
|
|
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
print $hookmanager->resPrint;
|
|
if (empty($reshook)) {
|
|
print $object->showOptionals($extrafields, 'edit', $parameters);
|
|
}
|
|
|
|
print '</table>';
|
|
|
|
// Reminders
|
|
if ($enablereminders) {
|
|
$filteruserid = $user->id;
|
|
if ($user->hasRight('agenda', 'allactions', 'read')) {
|
|
$filteruserid = 0;
|
|
}
|
|
$object->loadReminders('', $filteruserid, false);
|
|
|
|
print '<hr>';
|
|
|
|
if (count($object->reminders) > 0) {
|
|
$checked = 'checked';
|
|
$keys = array_keys($object->reminders);
|
|
$firstreminderId = array_shift($keys);
|
|
|
|
$actionCommReminder = $object->reminders[$firstreminderId];
|
|
} else {
|
|
$checked = '';
|
|
$actionCommReminder = new ActionCommReminder($db);
|
|
$actionCommReminder->offsetvalue = getDolGlobalInt('AGENDA_REMINDER_DEFAULT_OFFSET', 30);
|
|
$actionCommReminder->offsetunit = 'i';
|
|
$actionCommReminder->typeremind = 'email';
|
|
}
|
|
$disabled = '';
|
|
/*
|
|
if ($object->datep < dol_now()) {
|
|
//$disabled = 'disabled title="'.dol_escape_htmltag($langs->trans("EventExpired")).'"';
|
|
}
|
|
*/
|
|
|
|
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>';
|
|
|
|
print '<div class="reminderparameters" '.(empty($checked) ? 'style="display: none;"' : '').'>';
|
|
|
|
print '<br>';
|
|
|
|
print '<table class="border centpercent">';
|
|
|
|
// Reminder
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderTime").'</td><td colspan="3">';
|
|
print '<input type="number" name="offsetvalue" class="width50" value="'.$actionCommReminder->offsetvalue.'"> ';
|
|
print $form->selectTypeDuration('offsetunit', $actionCommReminder->offsetunit, $TDurationTypesExcluded);
|
|
print '</td></tr>';
|
|
|
|
// Reminder Type
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("ReminderType").'</td><td colspan="3">';
|
|
print $form->selectarray('selectremindertype', $TRemindTypes, $actionCommReminder->typeremind, 0, 0, 0, '', 0, 0, 0, '', 'minwidth200', 1);
|
|
print '</td></tr>';
|
|
|
|
$hide = '';
|
|
if ($actionCommReminder->typeremind == 'browser') {
|
|
$hide = 'style="display:none;"';
|
|
}
|
|
|
|
// Mail Model
|
|
if (getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
|
|
print '<tr '.$hide.'><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
|
|
print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1, 1, (string) $actionCommReminder->fk_email_template);
|
|
print '</td></tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
?>
|
|
<script type="text/javascript">
|
|
$(document).ready(function () {
|
|
$("#addreminder").click(function(){
|
|
if (this.checked) {
|
|
$(".reminderparameters").show();
|
|
} else {
|
|
$(".reminderparameters").hide();
|
|
}
|
|
});
|
|
$("#selectremindertype").change(function(){
|
|
var selected_option = $("#selectremindertype option:selected").val();
|
|
if(selected_option == "email") {
|
|
$("#select_actioncommsendmodel_mail").closest("tr").show();
|
|
} else {
|
|
$("#select_actioncommsendmodel_mail").closest("tr").hide();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
<?php
|
|
|
|
$reminderDefaultEventTypes = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EVENT_TYPES', '');
|
|
$reminderDefaultOffset = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET', 30);
|
|
$reminderDefaultUnit = getDolGlobalString('AGENDA_DEFAULT_REMINDER_OFFSET_UNIT');
|
|
$reminderDefaultEmailModel = getDolGlobalString('AGENDA_DEFAULT_REMINDER_EMAIL_MODEL');
|
|
|
|
print "\n".'<script type="text/javascript">';
|
|
print '$(document).ready(function () {
|
|
const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
|
|
$("#actioncode").change(function(){
|
|
var selected_event_type = $("#actioncode option:selected").val();
|
|
|
|
if (reminderDefaultEventTypes.includes(selected_event_type)) {
|
|
$(".reminderparameters").show();
|
|
$("#addreminder").prop("checked", true);
|
|
|
|
// Set period with default reminder period
|
|
$("#offsetvalue").val(\''.dol_escape_js($reminderDefaultOffset).'\');
|
|
$("#select_offsetunittype_duration").select2("destroy");
|
|
$("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
|
|
$("#select_offsetunittype_duration").select2();
|
|
|
|
$("#selectremindertype").select2("destroy");
|
|
$("#selectremindertype").val("email");
|
|
$("#selectremindertype").select2();
|
|
|
|
// Set default reminder mail model
|
|
$("#select_actioncommsendmodel_mail").closest("tr").show();
|
|
$("#select_actioncommsendmodel_mail").select2("destroy");
|
|
$("#select_actioncommsendmodel_mail").val(\''.dol_escape_js($reminderDefaultEmailModel).'\');
|
|
$("#select_actioncommsendmodel_mail").select2();
|
|
}
|
|
});
|
|
})';
|
|
print '</script>'."\n";
|
|
print '</div>'; // End of div for reminderparameters
|
|
}
|
|
|
|
print dol_get_fiche_end();
|
|
|
|
print $form->buttonsSaveCancel();
|
|
|
|
print '</form>';
|
|
} else {
|
|
print dol_get_fiche_head($head, 'card', $langs->trans("Action"), -1, 'action', 0, '', '', 0, '', 1);
|
|
|
|
$formconfirm = '';
|
|
|
|
// Clone event
|
|
if ($action == 'clone') {
|
|
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.GETPOST('id'), $langs->trans('ToClone'), $langs->trans('ConfirmCloneEvent', $object->label), 'confirm_clone', [], 'yes', 1);
|
|
}
|
|
|
|
// Call Hook formConfirm
|
|
$parameters = [];
|
|
$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
if (empty($reshook)) {
|
|
$formconfirm .= $hookmanager->resPrint;
|
|
} elseif ($reshook > 0) {
|
|
$formconfirm = $hookmanager->resPrint;
|
|
}
|
|
|
|
// Print form confirm
|
|
print $formconfirm;
|
|
|
|
$linkback = '';
|
|
// Link to other agenda views
|
|
$linkback .= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&restore_lastsearch_values=1">';
|
|
$linkback .= img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="pictoactionview pictofixedwidth"');
|
|
$linkback .= '<span class="hideonsmartphone">'.$langs->trans("BackToList").'</span>';
|
|
$linkback .= '</a>';
|
|
$linkback .= '</li>';
|
|
$linkback .= '<li class="noborder litext">';
|
|
$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').'">';
|
|
$linkback .= img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="pictoactionview pictofixedwidth"');
|
|
$linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewCal").'</span>';
|
|
$linkback .= '</a>';
|
|
$linkback .= '</li>';
|
|
$linkback .= '<li class="noborder litext">';
|
|
$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').'">';
|
|
$linkback .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview pictofixedwidth"');
|
|
$linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewWeek").'</span>';
|
|
$linkback .= '</a>';
|
|
$linkback .= '</li>';
|
|
$linkback .= '<li class="noborder litext">';
|
|
$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').'">';
|
|
$linkback .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview pictofixedwidth"');
|
|
$linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewDay").'</span>';
|
|
$linkback .= '</a>';
|
|
$linkback .= '</li>';
|
|
$linkback .= '<li class="noborder litext">';
|
|
$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').'">';
|
|
$linkback .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview pictofixedwidth"');
|
|
$linkback .= '<span class="hideonsmartphone">'.$langs->trans("ViewPerUser").'</span>';
|
|
$linkback .= '</a>';
|
|
|
|
// Add more views from hooks
|
|
$parameters = [];
|
|
$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
|
|
if (empty($reshook)) {
|
|
$linkback .= $hookmanager->resPrint;
|
|
} elseif ($reshook > 1) {
|
|
$linkback = $hookmanager->resPrint;
|
|
}
|
|
|
|
//$linkback.=$out;
|
|
|
|
$morehtmlref = '<div class="refidno">';
|
|
// Thirdparty
|
|
//$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
|
|
// Project
|
|
if (isModEnabled('project')) {
|
|
$langs->load("projects");
|
|
//$morehtmlref .= '<br>';
|
|
if ($usercancreate) {
|
|
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
|
|
if ($action != 'classify') {
|
|
$morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
|
|
}
|
|
$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');
|
|
} else {
|
|
if (!empty($object->fk_project)) {
|
|
$proj = new Project($db);
|
|
$proj->fetch($object->fk_project);
|
|
$morehtmlref .= $proj->getNomUrl(1);
|
|
if ($proj->title) {
|
|
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$morehtmlref .= '</div>';
|
|
|
|
|
|
dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'id', 'ref', $morehtmlref);
|
|
|
|
print '<div class="fichecenter">';
|
|
print '<div class="fichehalfleft">';
|
|
|
|
print '<div class="underbanner clearboth"></div>';
|
|
|
|
// Show event in view mode
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
// Type
|
|
if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
|
|
print '<tr><td class="titlefieldmiddle">'.$langs->trans("Type").'</td><td>';
|
|
$labeltype = ($langs->transnoentities("Action".$object->type_code) != "Action".$object->type_code) ? $langs->transnoentities("Action".$object->type_code) : $object->type_label;
|
|
$labeltoshow = $labeltype;
|
|
if ($object->code) {
|
|
$labeltoshow .= ' ('.$object->code.')';
|
|
}
|
|
print $object->getTypePicto('pictofixedwidth paddingright', $labeltoshow);
|
|
print $labeltype;
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Full day event
|
|
print '<tr><td class="titlefieldmiddle">'.$langs->trans("EventOnFullDay").'</td><td>'.yn($object->fulldayevent ? 1 : 0, 3).'</td></tr>';
|
|
|
|
$rowspan = 4;
|
|
if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
|
|
$rowspan++;
|
|
}
|
|
|
|
// Date start
|
|
print '<tr><td>'.$langs->trans("DateActionStart").'</td><td title="'.dol_print_date($object->datep, 'dayhoursec', 'tzuserrel').'">';
|
|
// Test a date before the 27 march and one after
|
|
//print dol_print_date($object->datep, 'dayhour', 'gmt');
|
|
//print dol_print_date($object->datep, 'dayhour', 'tzuser');
|
|
//print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
|
|
if (empty($object->fulldayevent)) {
|
|
print dol_print_date($object->datep, 'dayhour', 'tzuserrel');
|
|
} else {
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
print dol_print_date($object->datep, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
|
|
}
|
|
if ($object->percentage == 0 && $object->datep && $object->datep < ($now - $delay_warning)) {
|
|
print img_warning($langs->trans("Late"));
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
|
|
// Date end
|
|
print '<tr><td>'.$langs->trans("DateActionEnd").'</td><td title="'.dol_print_date($object->datef, 'dayhoursec', 'tzuserrel').'">';
|
|
if (empty($object->fulldayevent)) {
|
|
print dol_print_date($object->datef, 'dayhour', 'tzuserrel');
|
|
} else {
|
|
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
|
print dol_print_date($object->datef, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel'));
|
|
}
|
|
if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now - $delay_warning)) {
|
|
print img_warning($langs->trans("Late"));
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// Recurring event (into a series)
|
|
if ($object->recurid) {
|
|
print '<tr><td class="titlefieldmiddle">'.$langs->trans("RecurringEvent").'</td><td>';
|
|
print img_picto($langs->trans("EventPartOfARecurringSerie", $object->recurid), 'recurring', 'class="pictofixedwidth"');
|
|
$reg = [];
|
|
if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) {
|
|
print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
|
|
}
|
|
if (preg_match('/FREQ=YEARLY_BYYEARMONTHDAY(\d+)/', $object->recurrule, $reg)) {
|
|
print $langs->trans("EveryYear").' <span class="opacitymedium small">('.$langs->trans("DayOfYear").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Location
|
|
if (!getDolGlobalString('AGENDA_DISABLE_LOCATION')) {
|
|
print '<tr><td>'.$langs->trans("Location").'</td><td>'.$object->location.'</td></tr>';
|
|
}
|
|
|
|
// Assigned to user
|
|
print '<tr><td class="nowrap">'.$langs->trans("ActionAssignedTo").'</td><td>';
|
|
$listofuserid = [];
|
|
if (empty($donotclearsession)) {
|
|
if ($object->userownerid > 0) {
|
|
$listofuserid[$object->userownerid] = array(
|
|
'id' => $object->userownerid,
|
|
'transparency' => $object->transparency, // Force transparency on owner from property of event
|
|
'answer_status' => $object->userassigned[$object->userownerid]['answer_status'],
|
|
'mandatory' => $object->userassigned[$object->userownerid]['mandatory']
|
|
);
|
|
}
|
|
if (!empty($object->userassigned)) { // Now concat assigned users
|
|
// Restore array with key with same value than param 'id'
|
|
$tmplist1 = $object->userassigned;
|
|
foreach ($tmplist1 as $key => $val) {
|
|
if ($val['id'] && $val['id'] != $object->userownerid) {
|
|
$listofuserid[$val['id']] = $val;
|
|
}
|
|
}
|
|
}
|
|
$_SESSION[$sessionkeyassignedtouser] = json_encode($listofuserid);
|
|
} else {
|
|
if (!empty($_SESSION[$sessionkeyassignedtouser])) {
|
|
$listofuserid = json_decode($_SESSION[$sessionkeyassignedtouser], true);
|
|
}
|
|
}
|
|
|
|
$listofcontactid = []; // not used yet
|
|
$listofotherid = []; // not used yet
|
|
print '<div class="assignedtouser">';
|
|
print $form->select_dolusers_forevent('view', 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, '', ($object->datep != $object->datef) ? 1 : 0, $listofuserid, $listofcontactid, $listofotherid);
|
|
print '</div>';
|
|
/*
|
|
if ($object->datep != $object->datef && in_array($user->id,array_keys($listofuserid)))
|
|
{
|
|
print '<div class="myavailability">';
|
|
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
|
|
print '</div>';
|
|
}
|
|
*/
|
|
print ' </td></tr>';
|
|
|
|
// Categories
|
|
if (isModEnabled('category')) {
|
|
print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
|
|
print $form->showCategories($object->id, Categorie::TYPE_ACTIONCOMM, 1);
|
|
print "</td></tr>";
|
|
}
|
|
|
|
print '</table>';
|
|
|
|
print '</div>';
|
|
|
|
print '<div class="fichehalfright">';
|
|
|
|
print '<div class="underbanner clearboth"></div>';
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
if (isModEnabled("societe")) {
|
|
// Related company
|
|
print '<tr><td class="titlefield">'.$langs->trans("ActionOnCompany").'</td>';
|
|
print '<td>'.(is_object($object->thirdparty) && $object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : ('<span class="opacitymedium">'.$langs->trans("None").'</span>'));
|
|
if (is_object($object->thirdparty) && $object->thirdparty->id > 0 && $object->type_code == 'AC_TEL') {
|
|
if ($object->thirdparty->fetch($object->thirdparty->id)) {
|
|
print "<br>".dol_print_phone($object->thirdparty->phone);
|
|
}
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// Related contact
|
|
print '<tr><td>'.$langs->trans("ActionOnContact").'</td>';
|
|
print '<td>';
|
|
|
|
if (!empty($object->socpeopleassigned)) {
|
|
foreach ($object->socpeopleassigned as $cid => $Tab) {
|
|
$contact = new Contact($db);
|
|
$result = $contact->fetch($cid);
|
|
|
|
if ($result < 0) {
|
|
dol_print_error($db, $contact->error);
|
|
}
|
|
|
|
if ($result > 0) {
|
|
print $contact->getNomUrl(1);
|
|
if ($object->type_code == 'AC_TEL') {
|
|
if (!empty($contact->phone_pro)) {
|
|
print '('.dol_print_phone($contact->phone_pro).')';
|
|
}
|
|
}
|
|
print '<div class="paddingright"></div>';
|
|
}
|
|
}
|
|
} else {
|
|
print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Priority
|
|
if (getDolGlobalString('AGENDA_SUPPORT_PRIORITY_IN_EVENTS')) {
|
|
print '<tr><td class="nowrap" class="titlefield">' . $langs->trans("Priority") . '</td><td>';
|
|
print($object->priority ? $object->priority : '');
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table
|
|
// for such objects because there is already a dedicated field into table llx_actioncomm.
|
|
if (!empty($object->elementid) && !empty($object->elementtype) && !in_array($object->elementtype, array('societe', 'contact', 'project'))) {
|
|
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
|
print '<tr><td>'.$langs->trans("LinkedObject").'</td>';
|
|
$link = dolGetElementUrl($object->elementid, $object->elementtype, ($object->elementtype == 'user' ? -1 : 1));
|
|
print '<td>';
|
|
if (empty($link)) {
|
|
print '<span class="opacitymedium">'.$langs->trans("ObjectDeleted").'</span>';
|
|
} else {
|
|
print $link;
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
//mail information
|
|
if (!empty($object->email_msgid)) {
|
|
print '<tr><td>'.$langs->trans('MailTopic').'</td>';
|
|
print '<td>'.dol_escape_htmltag($object->email_subject).'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MailFrom').'</td>';
|
|
print '<td>'.dol_escape_htmltag($object->email_from).'</td></tr>';
|
|
print '<tr><td>'.$langs->trans('MailTo').'</td>';
|
|
print '<td>'.dol_escape_htmltag($object->email_to).'</td></tr>';
|
|
if (!empty($object->email_tocc)) {
|
|
print '<tr><td>'.$langs->trans('MailCC').'</td>';
|
|
print '<td>'.dol_escape_htmltag($object->email_tocc).'</td></tr>';
|
|
}
|
|
}
|
|
|
|
// Description
|
|
print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td class="wordbreak sensiblehtmlcontent">';
|
|
print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private));
|
|
print '</td></tr>';
|
|
|
|
// Other attributes
|
|
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
|
|
|
|
// Reminders
|
|
if ($enablereminders) {
|
|
$filteruserid = $user->id;
|
|
if ($user->hasRight('agenda', 'allactions', 'read')) {
|
|
$filteruserid = 0;
|
|
}
|
|
$object->loadReminders('', $filteruserid, false);
|
|
|
|
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Reminders").'</td><td>';
|
|
|
|
if (count($object->reminders) > 0) {
|
|
$tmpuserstatic = new User($db);
|
|
|
|
foreach ($object->reminders as $actioncommreminderid => $actioncommreminder) {
|
|
print $TRemindTypes[$actioncommreminder->typeremind]['label'];
|
|
if ($actioncommreminder->fk_user > 0) {
|
|
$tmpuserstatic->fetch($actioncommreminder->fk_user);
|
|
print ' ('.$tmpuserstatic->getNomUrl(0, '', 0, 0, 16).')';
|
|
}
|
|
print ' - '.$actioncommreminder->offsetvalue.' '.$TDurationTypes[$actioncommreminder->offsetunit];
|
|
|
|
if ($actioncommreminder->status == $actioncommreminder::STATUS_TODO) {
|
|
print ' - <span class="opacitymedium">';
|
|
print $langs->trans("NotSent");
|
|
print ' </span>';
|
|
} elseif ($actioncommreminder->status == $actioncommreminder::STATUS_DONE) {
|
|
print ' - <span class="opacitymedium">';
|
|
print $langs->trans("Done");
|
|
print ' </span>';
|
|
} elseif ($actioncommreminder->status == $actioncommreminder::STATUS_ERROR) {
|
|
print ' - <span class="opacitymedium">';
|
|
print $form->textwithpicto($langs->trans("Error"), $actioncommreminder->lasterror);
|
|
print ' </span>';
|
|
}
|
|
print '<br>';
|
|
}
|
|
}
|
|
|
|
print '</td></tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
|
|
print '</div>';
|
|
print '</div>';
|
|
print '<div class="clearboth"></div>';
|
|
|
|
print dol_get_fiche_end();
|
|
}
|
|
|
|
|
|
/*
|
|
* Action bar
|
|
*/
|
|
print '<div class="tabsAction">';
|
|
|
|
$parameters = [];
|
|
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
|
if (empty($reshook)) {
|
|
if ($action != 'edit') {
|
|
if ($user->hasRight('agenda', 'allactions', 'create') ||
|
|
(($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
|
|
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Modify").'</a></div>';
|
|
} else {
|
|
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Modify").'</a></div>';
|
|
}
|
|
|
|
if ($user->hasRight('agenda', 'allactions', 'create') ||
|
|
(($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
|
|
print '<div class="inline-block divButAction"><a class="butAction butActionClone" href="card.php?action=clone&object='.$object->element.'&id='.$object->id.'">'.$langs->trans("ToClone").'</a></div>';
|
|
} else {
|
|
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("ToClone").'</a></div>';
|
|
}
|
|
|
|
if ($usercandelete) {
|
|
print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Delete").'</a></div>';
|
|
} else {
|
|
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Delete").'</a></div>';
|
|
}
|
|
}
|
|
}
|
|
|
|
print '</div>';
|
|
|
|
if ($action != 'edit') {
|
|
if (!getDolGlobalString('AGENDA_DISABLE_BUILDDOC')) {
|
|
print '<div class="clearboth"></div><div class="fichecenter"><div class="fichehalfleft">';
|
|
print '<a name="builddoc"></a>'; // ancre
|
|
|
|
// Generated documents
|
|
$filedir = $conf->agenda->multidir_output[$conf->entity].'/'.$object->id;
|
|
$urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
|
|
|
|
$genallowed = $user->hasRight('agenda', 'myactions', 'read');
|
|
$delallowed = $user->hasRight('agenda', 'myactions', 'create');
|
|
|
|
print $formfile->showdocuments('actions', (string) $object->id, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 0, 0, '', '', '', $langs->getDefaultLang());
|
|
|
|
if (getDolGlobalString('AGENDA_ENABLE_LINKED_ELEMENTS')) {
|
|
// Show links to link elements
|
|
$tmparray = $form->showLinkToObjectBlock($object, [], array('myobject'), 1);
|
|
if (is_array($tmparray)) {
|
|
$linktoelem = $tmparray['linktoelem'];
|
|
$htmltoenteralink = $tmparray['htmltoenteralink'];
|
|
print $htmltoenteralink;
|
|
$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
|
|
} else {
|
|
// backward compatibility
|
|
$somethingshown = $form->showLinkedObjectBlock($object, $tmparray);
|
|
}
|
|
}
|
|
print '</div><div class="fichehalfright">';
|
|
|
|
print '</div></div>';
|
|
}
|
|
}
|
|
}
|
|
|
|
// End of page
|
|
llxFooter();
|
|
$db->close();
|