diff --git a/README.md b/README.md index 7d92664..9fd827e 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ version 4.0.x is compatible with GLPI 9.5 and needs ProcessMaker 3.3.0-RE-1.x (h version 4.3.x is compatible with GLPI 9.5 and needs ProcessMaker 3.3.0-RE-1.13 (https://github.com/tomolimo/processmaker-server/releases/latest) -version 4.4.x is compatible with GLPI 9.5 and needs ProcessMaker 3.3.0-RE-2.0 (https://github.com/tomolimo/processmaker-server/releases/latest) +version 4.6.x is compatible with GLPI 9.5 and needs ProcessMaker 3.3.0-RE-2.x (https://github.com/tomolimo/processmaker-server/releases/latest) -version 5.0.x is compatible with GLPI 10.0 and needs ProcessMaker 3.3.0-RE-2.0 (https://github.com/tomolimo/processmaker-server/releases/latest) +version 5.1.x is compatible with GLPI 10.0 and needs ProcessMaker 3.3.0-RE-2.0 (https://github.com/tomolimo/processmaker-server/releases/latest) -This plugin can run classic (ProcessMaker server v2) and BPMN (ProcessMaker server v3 and later) processes +This plugin can run classic (ProcessMaker server v2) and BPMN (ProcessMaker server v3) processes diff --git a/ajax/asynchronousdatas.php b/ajax/asynchronousdatas.php index 8013b38..47184ca 100644 --- a/ajax/asynchronousdatas.php +++ b/ajax/asynchronousdatas.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -53,11 +53,22 @@ if (isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD']=='OPTIONS $datas = json_decode($request_body, true); $asyncdata = new PluginProcessmakerCrontaskaction; - if (isset($datas['id']) && $asyncdata->getFromDB( $datas['id'] ) && $asyncdata->fields['state'] == PluginProcessmakerCrontaskaction::WAITING_DATA) { + + $ID = 0; + if (isset($_REQUEST['id'])) { + $ID = $_REQUEST['id']; + } + if (isset($datas['id'])) { + $ID = $datas['id']; + } + if ($ID && $asyncdata->getFromDB($ID) && $asyncdata->fields['state'] == PluginProcessmakerCrontaskaction::WAITING_DATA) { $initialdatas = json_decode($asyncdata->fields['formdata'], true); - $initialdatas['form'] = array_merge( $initialdatas['form'], $datas['form'] ); + if (isset($datas['form'])) { + $datas = $datas['form']; + } + $initialdatas['form'] = array_merge( $initialdatas['form'], $datas ); $formdata = json_encode($initialdatas, JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE); - $asyncdata->update( [ 'id' => $datas['id'], 'state' => PluginProcessmakerCrontaskaction::DATA_READY, 'formdata' => $formdata ] ); + $asyncdata->update( [ 'id' => $ID, 'state' => PluginProcessmakerCrontaskaction::DATA_READY, 'formdata' => $formdata ] ); $ret = [ 'code' => '0', 'message' => 'Done' ]; } else { $ret = [ 'code' => '2', 'message' => 'Case is not existing, or state is not WAITING_DATA' ]; diff --git a/ajax/case.php b/ajax/case.php new file mode 100644 index 0000000..b85bd00 --- /dev/null +++ b/ajax/case.php @@ -0,0 +1,52 @@ +. +-------------------------------------------------------------------------- + */ + +use Glpi\Application\View\TemplateRenderer; +include ("../../../inc/includes.php"); +$item = new $_REQUEST['itemtype']; +$item->getFromDB($_REQUEST['items_id']); +$countProcesses = []; +$cases = PluginProcessmakerCase::getAllCases($_REQUEST['itemtype'], $_REQUEST['items_id'], $countProcesses); +echo "
"; +echo "
"; +TemplateRenderer::getInstance()->display( + 'components\user\picture.html.twig', + [ + 'users_id' => Session::getLoginUserID(), + ] + ); +echo "
"; +echo "
"; +echo "
"; +echo "
"; +echo "
"; +echo "
"; +echo "
"; +PluginProcessmakerCase::showAddFormForItem($item, rand(), $countProcesses, true); +echo "
"; \ No newline at end of file diff --git a/ajax/dropdownProcesses.php b/ajax/dropdownProcesses.php index a1b7e1b..8bde91b 100644 --- a/ajax/dropdownProcesses.php +++ b/ajax/dropdownProcesses.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/ajax/dropdownTaskcategories.php b/ajax/dropdownTaskcategories.php index 113594e..5e93066 100644 --- a/ajax/dropdownTaskcategories.php +++ b/ajax/dropdownTaskcategories.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/ajax/dropdownTicketCategories.php b/ajax/dropdownTicketCategories.php index ef775ab..630733d 100644 --- a/ajax/dropdownTicketCategories.php +++ b/ajax/dropdownTicketCategories.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/ajax/dropdownUsers.php b/ajax/dropdownUsers.php index e881d2b..9fd41e6 100644 --- a/ajax/dropdownUsers.php +++ b/ajax/dropdownUsers.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -58,8 +58,7 @@ if (!isset($_REQUEST['all'])) { } $used = []; - -if (isset($_REQUEST['used'])) { +if (isset($_REQUEST['used']) && is_array($_REQUEST['used'])) { $used = $_REQUEST['used']; } @@ -98,7 +97,7 @@ $users = []; $count = 0; foreach ($res as $data) { $users[$data["id"]] = $dbu->formatUserName($data["id"], $data["name"], $data["realname"], - $data["firstname"], 0); + $data["firstname"], 0) . " (" . $data["name"] . ")"; $logins[$data["id"]] = $data["name"]; } diff --git a/ajax/selfservicedrafts.php b/ajax/selfservicedrafts.php index 49d0129..8c8fe5e 100644 --- a/ajax/selfservicedrafts.php +++ b/ajax/selfservicedrafts.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/ajax/task.php b/ajax/task.php new file mode 100644 index 0000000..d4db3b8 --- /dev/null +++ b/ajax/task.php @@ -0,0 +1,34 @@ +. +-------------------------------------------------------------------------- + */ + +include ("../../../inc/includes.php"); +if( isset($_REQUEST) && !empty($_REQUEST)) { + $Case = new PluginProcessmakerCase; + $Case->getFromDB($_REQUEST['cases_id']); + PluginProcessmakerTask::displayTabContentForItem($Case, $_REQUEST['tabnum']); +} diff --git a/ajax/task_users.php b/ajax/task_users.php index 5c3e588..52772ae 100644 --- a/ajax/task_users.php +++ b/ajax/task_users.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -59,11 +59,16 @@ $PM_SOAP = new PluginProcessmakerProcessmaker; $PM_DB = new PluginProcessmakerDB; echo "
"; -echo __('Re-assign task to', 'processmaker')." "; echo ""; echo ""; echo $commoninputs; +echo ''; +echo ''; +echo ''; + $can_unclaim = false; // by default $grp = false; $query = "SELECT TAS_GROUP_VARIABLE FROM TASK WHERE TAS_UID='".$_REQUEST['taskGuid']."' AND TAS_ASSIGN_TYPE='SELF_SERVICE';"; @@ -76,20 +81,53 @@ if ($PM_DB->numrows($res) > 0 && $row = $PM_DB->fetchAssoc($res)) { $grp = $PM_SOAP->getGLPIGroupIdForSelfServiceTask($_REQUEST['caseGuid'], $_REQUEST['taskGuid']); } } +$task_table = getTableForItemType($_REQUEST['tasktype']); $res = $DB->request([ 'SELECT' => [ 'pm.is_reassignreason_mandatory AS pm_is_reassignreason_mandatory', - 'gppp.is_reassignreason_mandatory AS gppp_is_reassignreason_mandatory' + 'gppp.is_reassignreason_mandatory AS gppp_is_reassignreason_mandatory', + 'pm.before_time AS pm_before_time', + 'pm.after_time AS pm_after_time', + 'pm.users_id AS pm_users_id', + 'gpptr.before_time AS tr_before_time', + 'gpptr.after_time AS tr_after_time', + 'gpptr.users_id AS tr_users_id', + 'gpptr.id AS plugin_processmaker_taskrecalls_id', + 'gtt.begin AS task_begin', + 'gtt.end AS task_end', + 'gpptr.when AS tr_when', + 'gppt.id AS pm_tasks_id' ], 'FROM' => 'glpi_plugin_processmaker_taskcategories AS pm', 'LEFT JOIN' => [ - 'glpi_plugin_processmaker_processes AS gppp' => [ - 'FKEY' => [ - 'gppp' => 'id', - 'pm' => 'plugin_processmaker_processes_id' + 'glpi_plugin_processmaker_processes AS gppp' => [ + 'ON' => [ + 'gppp' => 'id', + 'pm' => 'plugin_processmaker_processes_id' + ] + ], + 'glpi_plugin_processmaker_tasks as gppt' => [ + 'ON' => [ + 'pm' => 'id', + 'gppt' => 'plugin_processmaker_taskcategories_id', + ['AND' => ['gppt.items_id' => $_REQUEST['tasks_id'], + 'gppt.itemtype'=> $_REQUEST['tasktype']] + ] + ] + ], + 'glpi_plugin_processmaker_taskrecalls as gpptr' => [ + 'ON' => [ + 'gpptr' => 'plugin_processmaker_tasks_id', + 'gppt' => 'id' + ] + ], + $task_table . ' as gtt' => [ + 'ON' => [ + 'gtt' => 'id', + 'gppt' => 'items_id' + ] ] - ] ], 'WHERE' => [ 'pm.pm_task_guid' => $_REQUEST['taskGuid'] @@ -100,9 +138,10 @@ $res = $DB->request([ $taskCat = $res->current(); $ask_for_reason = PluginProcessmakerTaskCategory::inheritedReAssignReason($taskCat['pm_is_reassignreason_mandatory'], $taskCat['gppp_is_reassignreason_mandatory']); +echo ''; +echo ''; -if (Session::getLoginUserID() != $_REQUEST['users_id']) { - echo "  "; - echo ""; +echo ''; + + +echo ''; + +// check rights +$caneditreminders = Session::getCurrentInterface() == 'central' && $PM_SOAP->config['users_id'] != $_REQUEST['users_id']; + +if ($caneditreminders) { + echo ''; } +echo ''; +echo '
'; +echo "" . __('Re-assign task to', 'processmaker') . ""; +echo ''; PluginProcessmakerUser::dropdown( ['name' => 'users_id_recipient', 'value' => $_REQUEST['users_id'], - //'used' => $_REQUEST['used'], // not set to be able to alert when trying to re-assigned to the same user + 'used' => $_REQUEST['used'] ?? [], 'entity' => 0, //$item->fields["entities_id"], // not used, as any user can be assigned to any tasks 'entity_sons' => false, // not used, as any user can be assigned to any tasks 'right' => 'all', @@ -111,8 +150,9 @@ PluginProcessmakerUser::dropdown( ['name' => 'users_id_recipient', 'width' => '', 'specific_tags' => ['taskGuid' => $_REQUEST['taskGuid'], 'grpGuid' => ($grp !== false ? $grp['uid'] : 0)] ]); +echo ''; -echo "  "; echo ""; echo ""; @@ -205,10 +245,217 @@ echo HTML::scriptBlock(" }) "); +echo ''; +echo ''; +if (!isset($PM_SOAP->config)) { + $PM_SOAP->config = Config::getConfigurationValues('plugin:processmaker'); +} +if (Session::getLoginUserID() != $_REQUEST['users_id'] + && $PM_SOAP->config['users_id'] != $_REQUEST['users_id']) { + echo ""; +} +echo ''; + echo '
Automatic reminder settings 
'; + echo Html::scriptBlock(" + function showHideReminderSettings() { + if ($('.reminder_settings').css('display') == 'none') { + $('.reminder_settings').css('display', ''); + } else { + $('.reminder_settings').css('display', 'none'); + } + $('#reminder_arrow').toggleClass('fa-caret-up fa-caret-down'); + } + "); + echo '
'; + + +if ($caneditreminders) { + // add info on reminder + // show before time + // show after time + // show next date + // show user + // add submit button + echo Html::scriptBlock(" + function formatedTimestamp (d, hm_only) { + const date = d.toISOString().split('T')[0]; + const time = d.toTimeString().split(' ')[0]; + if (typeof hm_only === 'undefined' && hm_only === true) { + return date + ' ' + time; + } + const hm = time.split(':') + return date + ' ' + hm[0] + ':' + hm[1]; + } + + function computeNextDate (elt_name, new_date_name, ref_name, ope) { + var delta = $('[name=' + elt_name + ']').val() * 1000; // in milliseconds + var ref = $('[name=' + ref_name + ']').val(); // date_begin or date_end + var new_date = __('None', 'processmaker'); // by default + if (delta >= 0) { + if (ope === 'sub') { + delta = -delta; + } + new_date = formatedTimestamp(new Date(Date.parse(ref) + delta)); + var current_date = formatedTimestamp(new Date()); + if (new_date < current_date) { + new_date = formatedTimestamp(new Date(Date.parse(current_date) + delta)); + } + } + $('[name=' + new_date_name + ']').val(new_date); + $('#' + new_date_name).text(new_date); + } + + function selectUser (userid, username) { + // Set the actual_users_id value, creating a new option if necessary + if ($('[name=actual_users_id]').find('option[value=' + userid + ']').length) { + $('[name=actual_users_id]').val(userid).trigger('change'); + } else { + // Create a DOM Option and pre-select by default + var newOption = new Option(decodeURIComponent(username.replace(/\+/g, ' ')), userid, true, true); + // Append it to the select + $('[name=actual_users_id]').append(newOption).trigger('change'); + } + } + + function reset2Defaults () { + if ($('[name=actual_before_time]').val() != " . PluginProcessmakerTaskCategory::REMINDER_STOP . " + && $('[name=task_begin]').val() > '" . $_SESSION["glpi_currenttime"] . "') { + $('[name=actual_before_time]').val($('[name=default_before_time]').val()).trigger('change'); + } + + $('[name=actual_after_time]').val($('[name=default_after_time]').val()).trigger('change'); + + // Set the actual_users_id value, creating a new option if necessary + selectUser($('[name=default_users_id]').val(), $('[name=default_user_name]').val()); + } + "); + echo ""; + echo ""; + echo ""; + echo ""; + + echo ''; + echo ''; + + echo ""; + echo ""; + + $taskCat['pm_users_id'] = $taskCat['pm_users_id'] ?? 0; + echo ""; + + $user_info = urlencode($taskCat['pm_users_id'] > 0 ? getUserName($taskCat['pm_users_id']) : Dropdown::EMPTY_VALUE); + echo ""; + + echo ''; + + echo ''; + echo ''; + + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + + echo ''; + + echo ''; + echo ''; + echo ""; + + echo ''; + echo ''; + echo ""; + + echo ''; + + echo ''; + + echo ''; + + echo ''; +} + +echo '
'; + Html::closeForm(true); diff --git a/css/task.css b/css/task.css index 64f6112..e836274 100644 --- a/css/task.css +++ b/css/task.css @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -27,7 +27,7 @@ along with this plugin. If not, see . span.pm_task, a.pm_task { float: right; color: #fff !important; - border-radius: 8px; + border-radius: 4px; padding-left: 8px; line-height: 1.5; } @@ -43,4 +43,10 @@ span.pm_task_case { margin-left: 8px; flex: none; align-self: flex-start; +} + +td.pm_reminder { + border-left-color: lightgrey; + border-left-width: 1px; + border-left-style: solid; } \ No newline at end of file diff --git a/front/case.form.php b/front/case.form.php index 7376e70..3307a2e 100644 --- a/front/case.form.php +++ b/front/case.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/case.php b/front/case.php index f50fdea..53b3b45 100644 --- a/front/case.php +++ b/front/case.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/caselink.form.php b/front/caselink.form.php index 451c00d..bb90d5d 100644 --- a/front/caselink.form.php +++ b/front/caselink.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/caselink.php b/front/caselink.php index 633034a..3b81cce 100644 --- a/front/caselink.php +++ b/front/caselink.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/config.form.php b/front/config.form.php index 8870fd8..53708f9 100644 --- a/front/config.form.php +++ b/front/config.form.php @@ -1,5 +1,29 @@ . +-------------------------------------------------------------------------- */ include ( "../../../inc/includes.php"); diff --git a/front/crontaskaction.form.php b/front/crontaskaction.form.php index 16bdb1b..9ee90c8 100644 --- a/front/crontaskaction.form.php +++ b/front/crontaskaction.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/crontaskaction.php b/front/crontaskaction.php index 2409a7a..7591479 100644 --- a/front/crontaskaction.php +++ b/front/crontaskaction.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/document.send.php b/front/document.send.php index 6704154..98fa8ab 100644 --- a/front/document.send.php +++ b/front/document.send.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/index.php b/front/index.php index 3c3be91..ea1aa15 100644 --- a/front/index.php +++ b/front/index.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/process.form.php b/front/process.form.php index 167eb73..38d45ce 100644 --- a/front/process.form.php +++ b/front/process.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/process.php b/front/process.php index 348b35b..94f188d 100644 --- a/front/process.php +++ b/front/process.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/process_profile.form.php b/front/process_profile.form.php index 4601b46..e230131 100644 --- a/front/process_profile.form.php +++ b/front/process_profile.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/processmaker.form.php b/front/processmaker.form.php index 16313e8..cbba494 100644 --- a/front/processmaker.form.php +++ b/front/processmaker.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -51,17 +51,20 @@ switch ($_REQUEST["action"]) { //$task->getFromDBByQuery(" WHERE `plugin_processmaker_cases_id`=".$case->getID()); // normally there is only one and only one first task //$link .= '&forcetab=PluginProcessmakerTask$'.$task->getID(); - - Session::setActiveTab('PluginProcessmakerCase', 'PluginProcessmakerTask$'.$task->fields['id']); - $item = new $_REQUEST['itemtype']; - $item->getFromDB($_REQUEST['items_id']); - unset($_SERVER['REQUEST_URI']); // to prevent use of processmaker.form.php in NavigateList - Session::initNavigateListItems('PluginProcessmakerCase', - //TRANS : %1$s is the itemtype name, + if (!isset($_REQUEST['timeline'])) { + Session::setActiveTab('PluginProcessmakerCase', 'PluginProcessmakerTask$'.$task->fields['id']); + $item = new $_REQUEST['itemtype']; + $item->getFromDB($_REQUEST['items_id']); + unset($_SERVER['REQUEST_URI']); // to prevent use of processmaker.form.php in NavigateList + Session::initNavigateListItems('PluginProcessmakerCase', + //TRANS : %1$s is the itemtype name, // %2$s is the name of the item (used for headings of a list) - sprintf('%1$s = %2$s', - $_REQUEST['itemtype']::getTypeName(1), $item->fields["name"])); - Html::redirect($link); + sprintf('%1$s = %2$s', + $_REQUEST['itemtype']::getTypeName(1), $item->fields["name"])); + Html::redirect($link); + } else if ($_REQUEST['timeline']) { + Html::back(); + } } Html::back(); } else { @@ -138,7 +141,7 @@ switch ($_REQUEST["action"]) { } } } elseif (isset($_REQUEST['reminder'])) { - // send notification remider as requested for this task + // send notification reminder as requested for this task $locCase = new PluginProcessmakerCase; $locCase->getFromDB($_REQUEST['cases_id']); @@ -151,6 +154,71 @@ switch ($_REQUEST["action"]) { // send notification now! $pm_task->sendNotification('task_reminder', $glpi_task, $glpi_item, $locCase); + + // Add a follow-up in the hosting item to indicate the sending of the reminder + $fu = new ITILFollowup(); + $input = $fu->fields; + + $fucontent = sprintf( + __("Case: '%s',
Task: '%s',
A reminder has been sent to:
", 'processmaker'), + $locCase->fields['name'], + Dropdown::getDropdownName("glpi_taskcategories", $glpi_task->fields["taskcategories_id"]) + ); + + if (isset($glpi_task->fields['users_id_tech']) && $glpi_task->fields['users_id_tech'] > 0) { + // get infos for user + $dbu = new DbUtils; + $userinfos = $dbu->getUserName($glpi_task->fields['users_id_tech'], 2); + $fucontent .= "-> " . $userinfos['name'] . "
"; + } + + if (isset($glpi_task->fields['groups_id_tech']) && $glpi_task->fields['groups_id_tech'] > 0) { + // get infos for group + $grp = new Group(); + $grp->getFromDB($glpi_task->fields['groups_id_tech']); + $fucontent .= "-> " . $grp->fields['name'] . "
"; + } + + $input['content'] = $DB->escape($fucontent); + $input['is_private'] = 0; + //$input['requesttypes_id'] = ; + $input['items_id'] = $_REQUEST['items_id']; + $input['users_id'] = Session::getLoginUserID(true); + $input['itemtype'] = $_REQUEST['itemtype']; + + $fu->add($input); + + } elseif (isset($_REQUEST['reminder_settings'])) { + // here we must add/update the taskrecalls + $recall = new PluginProcessmakerTaskrecall(); + // if the new_when is less than glpi_currenttime, then set it to glpi_currenttime + // to prevent send of many "after reminders" in case of late cron that missed several "after reminders" + // if the new_when is less than glpi_currenttime, then set it to glpi_currenttime + $new_when = -1; // by default will delete any records + if (isset($_REQUEST['actual_before_time']) && $_REQUEST['actual_before_time'] >= 0) { + $new_when = $_REQUEST['next_reminder_before']; + } elseif ($_REQUEST['actual_after_time'] >= 0) { + $new_when = $_REQUEST['next_reminder_after']; + } + if ($new_when !== -1 && $_REQUEST['plugin_processmaker_taskrecalls_id'] > 0) { + $recall->update([ + 'id' => $_REQUEST['plugin_processmaker_taskrecalls_id'], + 'before_time' => $_REQUEST['actual_before_time'], + 'after_time' => $_REQUEST['actual_after_time'], + 'when' => $new_when, + 'users_id' => $_REQUEST['actual_users_id'] + ]); + } elseif ($new_when !== -1) { + $recall->add([ + 'plugin_processmaker_tasks_id' => $_REQUEST['plugin_processmaker_tasks_id'], + 'before_time' => $_REQUEST['actual_before_time'], + 'after_time' => $_REQUEST['actual_after_time'], + 'when' => $new_when, + 'users_id' => $_REQUEST['actual_users_id'] + ]); + } elseif ($_REQUEST['plugin_processmaker_taskrecalls_id'] > 0) { + $recall->delete(['id' => $_REQUEST['plugin_processmaker_taskrecalls_id']]); + } } } diff --git a/front/processmaker.helpdesk.form.php b/front/processmaker.helpdesk.form.php index 58780be..9a76487 100644 --- a/front/processmaker.helpdesk.form.php +++ b/front/processmaker.helpdesk.form.php @@ -3,7 +3,7 @@ use Symfony\Component\DomCrawler\Crawler; /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -108,8 +108,15 @@ function processMakerShowCase($users_id, $from_helpdesk) { $tkt->showFormHelpdesk($users_id); $buffer = ob_get_clean(); + //if (ob_get_level() > 1) { + // echo $buffer; + // $buffer = ob_get_clean(); + //} + + //to change this HTML code + $rand = rand(); + $buffer = preg_replace(['@\s+`@',"@'',@", "@ @", "@\s+`;@", "@`@", "@`@"], ["icon_span_$rand`","'post_span_$rand',", "nbsp_$rand", "icon_button_$rand`;", "span_$rand`", "icon_$rand`"], $buffer); - // to change this HTML code $crawler = new Crawler(); $crawler->addHtmlContent($buffer); @@ -122,7 +129,7 @@ function processMakerShowCase($users_id, $from_helpdesk) { $crawler->filter('[name=add]')->getNode(0)->setAttribute('style', 'display:none;'); // add an input for processguid in the form - $formNode = $crawler->filter('#itil-form'); + $formNode = $crawler->filter('div.card'); $input = $formNode->getNode(0)->appendChild(new DOMElement('input')); $input->setAttribute('name', 'processmaker_process_guid'); $input->setAttribute('type', 'hidden'); @@ -191,10 +198,13 @@ function processMakerShowCase($users_id, $from_helpdesk) { ])); $iframe->setAttribute( 'src', -"{$PM_SOAP->serverURL}/cases/cases_Open?sid={$PM_SOAP->getPMSessionID()}&APP_UID={$caseInfo->caseId}&{$paramsURL}&glpi_data={$glpi_data}" - ); + "{$PM_SOAP->serverURL}/cases/cases_Open?sid={$PM_SOAP->getPMSessionID()}&APP_UID={$caseInfo->caseId}&{$paramsURL}&glpi_data={$glpi_data}" + ); - echo $crawler->html(); + $buffer = $crawler->html(); + $buffer = str_replace(["icon_span_$rand`", "'post_span_$rand',", "nbsp_$rand", "icon_button_$rand`;", "span_$rand`", "icon_$rand`"], [' `', "'',", " ", " `;", "`", "`"], $buffer); + + echo $buffer; } } diff --git a/front/taskcategory.form.php b/front/taskcategory.form.php index c37cb1b..8929298 100644 --- a/front/taskcategory.form.php +++ b/front/taskcategory.form.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/front/tracking.injector.php b/front/tracking.injector.php index 084c337..b05eb9b 100644 --- a/front/tracking.injector.php +++ b/front/tracking.injector.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/hook.php b/hook.php index 0e28564..fcce692 100644 --- a/hook.php +++ b/hook.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -72,8 +72,9 @@ function plugin_processmaker_install() { CronTask::Register('PluginProcessmakerProcessmaker', 'pmusers', DAY_TIMESTAMP, ['state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]); CronTask::Register('PluginProcessmakerProcessmaker', 'pmorphancases', DAY_TIMESTAMP, ['param' => 10, 'state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]); CronTask::Register('PluginProcessmakerProcessmaker', 'pmtaskactions', MINUTE_TIMESTAMP, ['state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]); + CronTask::Register('PluginProcessmakerTaskcategory', 'pmreminders', 5*MINUTE_TIMESTAMP, ['state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]); - // required because autoload doesn't work for unactive plugin' + // required because autoload doesn't work for inactive plugin' include_once(PLUGIN_PROCESSMAKER_ROOT . "/inc/profile.class.php"); PluginProcessmakerProfile::createAdminAccess($_SESSION['glpiactiveprofile']['id']); @@ -90,18 +91,14 @@ function plugin_processmaker_uninstall() { function plugin_processmaker_getAddSearchOptionsNew($itemtype) { - $name = _n('Process Case', 'Process Cases', Session::getPluralNumber(), 'processmaker'); - $tab = []; - $tab[] = [ - 'id' => 'processmaker', - 'name' => $name + + if (in_array($itemtype, ['Ticket', 'Change', 'Problem'])) { + $tab[] = [ + 'id' => 'processmaker', + 'name' => _n('Process Case', 'Process Cases', Session::getPluralNumber(), 'processmaker') ]; - // TODO add Change and Problem + other fields to the search - $objects = ['Ticket', 'Change', 'Problem']; - - if (in_array($itemtype, $objects)) { $tab[] = [ 'id' => 10001, 'table' => PluginProcessmakerCase::getTable(), @@ -191,20 +188,199 @@ function plugin_processmaker_getAddSearchOptionsNew($itemtype) { ]; } - return $tab; + + if ($itemtype == 'TaskCategory') { + $tab[] = [ + 'id' => 'processmaker', + 'name' => _n('Process task category', 'Process task categories', Session::getPluralNumber(), 'processmaker') + ]; + + $tab[] = [ + 'id' => 20000, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'taskcategories_id', + 'massiveaction' => false, + 'name' => __('Process task', 'processmaker'), + 'datatype' => 'itemlink', + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20001, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'is_start', + 'massiveaction' => false, + 'name' => __('Start', 'processmaker'), + 'datatype' => 'bool', + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20002, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'is_active', + 'massiveaction' => false, + 'name' => __('Active', 'processmaker'), + 'datatype' => 'bool', + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20003, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'is_subprocess', + 'massiveaction' => false, + 'name' => __('Sub-process', 'processmaker'), + 'datatype' => 'bool', + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20004, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'is_reassignreason_mandatory', + 'massiveaction' => false, + 'name' => __('Force re-assign reason', 'processmaker'), + 'datatype' => 'specific', + 'nosearch' => true, + 'nodisplay' => true, + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20005, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'before_time', + 'massiveaction' => false, + 'name' => __('Reminder (before task begin)', 'processmaker'), + 'datatype' => 'specific', + 'searchequalsonfield' => true, + 'searchtype' => [ + 'equals', + 'notequals', + 'lessthan', + 'morethan' + ], + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + $tab[] = [ + 'id' => 20006, + 'table' => User::getTable(), + 'field' => 'name', + 'massiveaction' => false, + 'name' => __('Reminder sender', 'processmaker'), + 'datatype' => 'dropdown', + 'linkfield' => 'users_id', + 'joinparams' => [ + 'beforejoin' => [ + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'joinparams' => [ + 'jointype' => 'child', + ] + ] + ] + ]; + + $tab[] = [ + 'id' => 20007, + 'table' => PluginProcessmakerTaskCategory::getTable(), + 'field' => 'after_time', + 'massiveaction' => false, + 'name' => __('Reminder (after task end)', 'processmaker'), + 'datatype' => 'specific', + 'searchequalsonfield' => true, + 'searchtype' => [ + 'equals', + 'notequals', + 'lessthan', + 'morethan' + ], + 'joinparams' => [ + 'jointype' => 'child' + ] + ]; + + // $tab[] = [ + // 'id' => 20008, + // 'table' => PluginProcessmakerTaskCategory::getTable(), + // 'field' => 'reminder_overdue_frequency', + // 'massiveaction' => false, + // 'name' => __('Reminder frequency', 'processmaker'), + // 'datatype' => 'specific', + // 'searchequalsonfield' => true, + // 'searchtype' => [ + // 'equals', + // 'notequals', + // ], + // 'joinparams' => [ + // 'jointype' => 'child', + // ] + //]; + } + + return $tab; } -//function plugin_processmaker_addWhere($link, $nott, $itemtype, $ID, $val, $searchtype) { +function plugin_processmaker_addWhere($link, $nott, $itemtype, $ID, $val, $searchtype) { + if ($itemtype == 'TaskCategory' && $ID == 20005) { // 20005 == before_time + switch ($searchtype) { + case 'lessthan': + if ($nott) { + return "$link (`glpi_plugin_processmaker_taskcategories`.`before_time` <= $val)"; + } else { + return "$link (`glpi_plugin_processmaker_taskcategories`.`before_time` > $val)"; + } + break; + case 'morethan': + if ($nott) { + return "$link (`glpi_plugin_processmaker_taskcategories`.`before_time` >= $val)"; + } else { + return "$link (`glpi_plugin_processmaker_taskcategories`.`before_time` < $val)"; + } + break; + } + } + if ($itemtype == 'TaskCategory' && $ID == 20007) { // 20007 == after_time + switch ($searchtype) { + case 'lessthan': + if ($nott) { + return "$link (`glpi_plugin_processmaker_taskcategories`.`after_time` >= $val)"; + } else { + return "$link (`glpi_plugin_processmaker_taskcategories`.`after_time` < $val)"; + } + break; + case 'morethan': + if ($nott) { + return "$link (`glpi_plugin_processmaker_taskcategories`.`after_time` <= $val)"; + } else { + return "$link (`glpi_plugin_processmaker_taskcategories`.`after_time` > $val)"; + } + break; + } + } -// return ''; + return ''; +} + + +//function plugin_processmaker_giveItem($itemtype, $ID, $data, $num) { +// echo ''; //} -function plugin_processmaker_giveItem($itemtype, $ID, $data, $num) { - echo ''; -} - - /** * Summary of plugin_pre_item_update_processmaker * @param CommonITILObject $parm is an object @@ -491,6 +667,9 @@ function plugin_item_update_processmaker_tasks($parm) { ], [], false); $externalapplicationparams['id'] = $cronactionid; + if ($externalapplication) { + $externalapplicationparams['callback'] .= "?id=$cronactionid"; + } $externalapplicationparams = json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT); // add to the crontaskcation the id of the crontaskaction itself in the postdata $cronaction->update([ @@ -545,7 +724,7 @@ function plugin_item_update_processmaker_tasks($parm) { // add to the crontaskaction the response of the remote API $cronaction->update([ 'id' => $cronactionid, - 'retcode' => ($response === false ? $error : $response) + 'retcode' => ($response === false ? $error : $DB->escape($response)) ], false); curl_close ($ch); diff --git a/inc/case.class.php b/inc/case.class.php index 0bb1a91..e7ebeff 100644 --- a/inc/case.class.php +++ b/inc/case.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -519,7 +519,7 @@ class PluginProcessmakerCase extends CommonDBTM { echo "".__('Current task(s) properties', 'processmaker').""; - if (property_exists($caseInfo, 'currentUsers') && count($caseInfo->currentUsers) > 0) { + if (property_exists($caseInfo, 'currentUsers') && count($caseInfo->currentUsers) > 0 && $caseInfo->caseStatus != self::CANCELLED) { echo " ".__('Task', 'processmaker')." ".__('Task guid', 'processmaker')." @@ -675,9 +675,9 @@ class PluginProcessmakerCase extends CommonDBTM { // order task by "current user", then by "to be claimed", and then push to end "tasks assigned to another user" // then by delindex ASC in these three parts - usort($utasks, 'self::localSortTasks'); - usort($tbctasks, 'self::localSortTasks'); - usort($infotasks, 'self::localSortTasks'); + usort($utasks, 'PluginProcessmakerCase::localSortTasks'); + usort($tbctasks, 'PluginProcessmakerCase::localSortTasks'); + usort($infotasks, 'PluginProcessmakerCase::localSortTasks'); return array_merge($utasks, $tbctasks, $infotasks); } @@ -767,39 +767,41 @@ class PluginProcessmakerCase extends CommonDBTM { $canupdate = $item->can($items_id, UPDATE); $rand = mt_rand(); - $res = $DB->request([ - 'SELECT' => ['gppc.id AS assocID', 'gppc.id AS id', 'gppp.id AS pid', 'gppp.name AS pname', 'gppc.case_status', 'gppc.plugin_processmaker_cases_id'], - 'FROM' => 'glpi_plugin_processmaker_cases AS gppc', - 'LEFT JOIN' => [ - 'glpi_plugin_processmaker_processes AS gppp' => [ - 'FKEY' => [ - 'gppp' => 'id', - 'gppc' => 'plugin_processmaker_processes_id'] - ] - ], - 'WHERE' => [ - 'AND' => [ - 'gppc.itemtype' => $itemtype, - 'gppc.items_id' => $items_id - ] - ] - ]); - - $cases = []; - $used = []; - $pid = []; - if ($numrows = $res->numrows()) { - foreach ($res as $data) { - $cases[$data['id']] = $data; - $used[$data['id']] = $data['id']; - if (isset($pid[$data['pid']])) { - $pid[$data['pid']] += 1; - } else { - $pid[$data['pid']] = 1; - } - } - } + //$res = $DB->request([ + // 'SELECT' => ['gppc.id AS assocID', 'gppc.id AS id', 'gppp.id AS pid', 'gppp.name AS pname', 'gppc.case_status', 'gppc.plugin_processmaker_cases_id'], + // 'FROM' => 'glpi_plugin_processmaker_cases AS gppc', + // 'LEFT JOIN' => [ + // 'glpi_plugin_processmaker_processes AS gppp' => [ + // 'FKEY' => [ + // 'gppp' => 'id', + // 'gppc' => 'plugin_processmaker_processes_id'] + // ] + // ], + // 'WHERE' => [ + // 'AND' => [ + // 'gppc.itemtype' => $itemtype, + // 'gppc.items_id' => $items_id + // ] + // ] + // ]); + //$cases = []; + //$used = []; + //$pid = []; + //if ($numrows = $res->numrows()) { + // foreach ($res as $data) { + // $cases[$data['id']] = $data; + // $used[$data['id']] = $data['id']; + // if (isset($pid[$data['pid']])) { + // $pid[$data['pid']] += 1; + // } else { + // $pid[$data['pid']] = 1; + // } + // } + //} + $countProcesses = []; + $cases = self::getAllCases($itemtype, $items_id, $countProcesses); + $numrows = count($cases); $columns = ['pname' => __('Process', 'processmaker'), 'name' => __('Case title', 'processmaker'), 'status' => __('Status', 'processmaker'), @@ -813,41 +815,42 @@ class PluginProcessmakerCase extends CommonDBTM { && $_SESSION['glpiactiveprofile']['interface'] != 'helpdesk' && ($numrows < $PM_SOAP->config['max_cases_per_item'] || $PM_SOAP->config['max_cases_per_item'] == 0)) { - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; + //echo "
"; + //echo ""; + //echo ""; + //echo ""; + //echo ""; - echo ""; - echo ""; + //echo "
".__('Add a new case', 'processmaker')."
"; + //echo ""; - echo "
".__('Add a new case', 'processmaker')."
"; - echo __('Select the process you want to add', 'processmaker'); - echo ""; - $condition['is_active'] = 1; - if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::INCIDENT_TYPE) { - $condition['is_incident'] = 1; - } else if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::DEMAND_TYPE) { - $condition['is_request'] = 1; - } else { - $condition['is_'.strtolower($itemtype)] = 1; - //$is_itemtype = "AND is_".strtolower($itemtype)."=1"; - } - PluginProcessmakerProcess::dropdown(['value' => 0, - 'entity' => $item->fields['entities_id'], - 'name' => 'plugin_processmaker_processes_id', - 'condition' => $condition, - 'specific_tags' => [ - 'count_cases_per_item' => $pid, - 'process_restrict' => 1 - ] - ]); - echo ""; - echo ""; - echo "
"; - Html::closeForm(); - echo "
"; + //echo ""; + //echo __('Select the process you want to add', 'processmaker'); + //echo ""; + //$condition['is_active'] = 1; + //if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::INCIDENT_TYPE) { + // $condition['is_incident'] = 1; + //} else if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::DEMAND_TYPE) { + // $condition['is_request'] = 1; + //} else { + // $condition['is_'.strtolower($itemtype)] = 1; + // //$is_itemtype = "AND is_".strtolower($itemtype)."=1"; + //} + //PluginProcessmakerProcess::dropdown(['value' => 0, + // 'entity' => $item->fields['entities_id'], + // 'name' => 'plugin_processmaker_processes_id', + // 'condition' => $condition, + // 'specific_tags' => [ + // 'count_cases_per_item' => $pid, + // 'process_restrict' => 1 + // ] + // ]); + //echo ""; + //echo ""; + //echo ""; + //Html::closeForm(); + //echo "
"; + self::showAddFormForItem($item, $rand, $countProcesses); } echo "
"; @@ -935,6 +938,85 @@ class PluginProcessmakerCase extends CommonDBTM { echo "
"; } + static function getAllCases($itemtype, $items_id, &$count_processes = []):array { + global $DB; + + $res = $DB->request([ + 'SELECT' => ['gppc.id AS assocID', 'gppc.id AS id', 'gppp.id AS pid', 'gppp.name AS pname', 'gppc.case_status', 'gppc.plugin_processmaker_cases_id'], + 'FROM' => 'glpi_plugin_processmaker_cases AS gppc', + 'LEFT JOIN' => [ + 'glpi_plugin_processmaker_processes AS gppp' => [ + 'FKEY' => [ + 'gppp' => 'id', + 'gppc' => 'plugin_processmaker_processes_id'] + ] + ], + 'WHERE' => [ + 'AND' => [ + 'gppc.itemtype' => $itemtype, + 'gppc.items_id' => $items_id + ] + ] + ]); + $cases = []; + if ($numrows = $res->numrows()) { + foreach ($res as $data) { + $cases[$data['id']] = $data; + } + } + foreach ($cases as $data) { + if (isset($count_processes[$data['pid']])) { + $count_processes[$data['pid']] += 1; + } else { + $count_processes[$data['pid']] = 1; + } + } + return $cases; + } + + static function showAddFormForItem(CommonDBTM $item, $rand, $pid, $timeline = false) { + $items_id = $item->getField('id'); + $itemtype = $item->getType(); + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + if ($timeline) { + echo ""; + } + + echo ""; + echo ""; + + echo "
".__('Add a new case', 'processmaker')."
"; + echo __('Select the process you want to add', 'processmaker'); + echo ""; + $condition['is_active'] = 1; + if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::INCIDENT_TYPE) { + $condition['is_incident'] = 1; + } else if ($itemtype == 'Ticket' && $item->fields['type'] == Ticket::DEMAND_TYPE) { + $condition['is_request'] = 1; + } else { + $condition['is_'.strtolower($itemtype)] = 1; + //$is_itemtype = "AND is_".strtolower($itemtype)."=1"; + } + PluginProcessmakerProcess::dropdown(['value' => 0, + 'entity' => $item->fields['entities_id'], + 'name' => 'plugin_processmaker_processes_id', + 'condition' => $condition, + 'specific_tags' => [ + 'count_cases_per_item' => $pid, + 'process_restrict' => 1 + ] + ]); + echo ""; + echo ""; + echo "
"; + Html::closeForm(); + echo "
"; + } + /** * Summary of displayTabContentForItem * @param CommonGLPI $item @@ -997,6 +1079,9 @@ class PluginProcessmakerCase extends CommonDBTM { * @return true if case and tasks have been deleted from associated item and from case table */ function deleteCase() { + global $DB; + self::deleteReminders($this->fields['id']); + return $this->delete(['id' => $this->getID()]); } @@ -1030,17 +1115,28 @@ class PluginProcessmakerCase extends CommonDBTM { ] ]); if ($res) { - $ret = true; + $ret = true; + // Delete task reminder on cancelCase + self::deleteReminders($this->fields['id']); } - //$query = "UPDATE glpi_".$this->fields['itemtype']."tasks SET state=0,users_id_tech=0,begin=NULL,end=NULL WHERE state=1 AND id in (select items_id from glpi_plugin_processmaker_tasks where plugin_processmaker_cases_id='".$this->fields['id']."')"; - //if ($DB->query( $query )) { - // $ret = true; - //} } return $ret; } - + /** + * Summary of deleteReminders + */ + static function deleteReminders($id) { + global $DB; + if ($id) { + $sub = new QuerySubQuery([ + 'SELECT' => 'id', + 'FROM' => 'glpi_plugin_processmaker_tasks', + 'WHERE' => ['plugin_processmaker_cases_id' => $id] + ]); + $DB->deleteOrDie('glpi_plugin_processmaker_taskrecalls', ['plugin_processmaker_tasks_id' => $sub]); + } + } /** * Summary of cancelCase @@ -1634,7 +1730,7 @@ class PluginProcessmakerCase extends CommonDBTM { if ($resultPM->status_code === 0 && $item->cancelCase()) { $ma->itemDone(__CLASS__, $pid, MassiveAction::ACTION_OK); - $ma->addMessage($pid.": ".__('Case has been cancelled!', 'processmaker')); + //$ma->addMessage($pid.": ".__('Case has been cancelled!', 'processmaker')); } else { $ma->itemDone(__CLASS__, $pid, MassiveAction::ACTION_KO); $ma->addMessage($pid.": ".__('Unable to cancel case!', 'processmaker')); diff --git a/inc/casechangelog.class.php b/inc/casechangelog.class.php index 88418f5..4c9f698 100644 --- a/inc/casechangelog.class.php +++ b/inc/casechangelog.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/casehistory.class.php b/inc/casehistory.class.php index cd2ba5b..185c954 100644 --- a/inc/casehistory.class.php +++ b/inc/casehistory.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/casehistorydynaformpage.class.php b/inc/casehistorydynaformpage.class.php index 5f57eff..d83487f 100644 --- a/inc/casehistorydynaformpage.class.php +++ b/inc/casehistorydynaformpage.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/caselink.class.php b/inc/caselink.class.php index cc88b80..8a05a73 100644 --- a/inc/caselink.class.php +++ b/inc/caselink.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/caselinkaction.class.php b/inc/caselinkaction.class.php index 021f6e1..5fe927d 100644 --- a/inc/caselinkaction.class.php +++ b/inc/caselinkaction.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/casemap.class.php b/inc/casemap.class.php index 17cfb5c..ea063b0 100644 --- a/inc/casemap.class.php +++ b/inc/casemap.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/config.class.php b/inc/config.class.php index 3fd9445..97fa3ec 100644 --- a/inc/config.class.php +++ b/inc/config.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/crontaskaction.class.php b/inc/crontaskaction.class.php index ef6e2d8..632762d 100644 --- a/inc/crontaskaction.class.php +++ b/inc/crontaskaction.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/db.class.php b/inc/db.class.php index 3160b47..11852e9 100644 --- a/inc/db.class.php +++ b/inc/db.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/document.class.php b/inc/document.class.php index 391da9d..9fccf3b 100644 --- a/inc/document.class.php +++ b/inc/document.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/menu.class.php b/inc/menu.class.php index 1268b5e..7063e28 100644 --- a/inc/menu.class.php +++ b/inc/menu.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/notificationtargetcase.class.php b/inc/notificationtargetcase.class.php index 2020e05..c7de457 100644 --- a/inc/notificationtargetcase.class.php +++ b/inc/notificationtargetcase.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/notificationtargetprocessmaker.class.php b/inc/notificationtargetprocessmaker.class.php index c5e391e..4c3ba23 100644 --- a/inc/notificationtargetprocessmaker.class.php +++ b/inc/notificationtargetprocessmaker.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/notificationtargettask.class.php b/inc/notificationtargettask.class.php index c343460..b017040 100644 --- a/inc/notificationtargettask.class.php +++ b/inc/notificationtargettask.class.php @@ -3,7 +3,7 @@ use Glpi\Toolbox\Sanitizer; /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -44,11 +44,24 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific 'task_reassign' => ['event' => 'task_reassign_', 'label' => __('Task re-assign'), 'glpi' => 'update_task'], 'task_unclaim' => ['event' => 'task_unclaim_', 'label' => __('Task un-claim'), 'glpi' => 'update_task'], 'task_done' => ['event' => 'task_done_', 'label' => __('Task done'), 'glpi' => 'update_task'], - 'task_reminder' => ['event' => 'task_reminder_', 'label' => __('Task reminder'), 'glpi' => 'update_task'] + 'task_reminder' => ['event' => 'task_reminder_', 'label' => __('Task reminder'), 'glpi' => 'update_task'], + 'task_overdue' => ['event' => 'task_overdue_', 'label' => __('Task overdue'), 'glpi' => 'update_task'] ]; } + public function getSender(): array { + $sender = parent::getSender(); + $users_id = $this->obj->getSender(); + if ($users_id > 0) { + $usr = new User(); + $usr->getFromDB($users_id); + $sender['name'] = $usr->getFriendlyName(); + $sender['email'] = $usr->getDefaultEmail(); + } + return $sender; + } + /** * Summary of getDefaultGLPIEvents * Will return the GLPI default task event matching a self type diff --git a/inc/process.class.php b/inc/process.class.php index b7f9029..85a80a4 100644 --- a/inc/process.class.php +++ b/inc/process.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -329,7 +329,7 @@ class PluginProcessmakerProcess extends CommonDBTM { global $DB, $PM_SOAP; $dbu = new DbUtils; $pmCurrentProcesses = []; - + PluginProcessmakerProcessCategory::refreshCategories(); // then refresh list of available process from PM to inner table $PM_SOAP->login( true ); $pmProcessList = $PM_SOAP->processList(); @@ -352,6 +352,9 @@ class PluginProcessmakerProcess extends CommonDBTM { } else { $glpiprocess->updateTaskCategory( $pmMainTaskCat ); } + if (!$glpiprocess->fields['plugin_processmaker_processcategories_id']) { + $glpiprocess->updateProcessCategory($process->category_guid); + } } else { // create it if (isset( $process->project_type )) { @@ -360,7 +363,12 @@ class PluginProcessmakerProcess extends CommonDBTM { $project_type = 'classic'; } - if ($glpiprocess->add( [ 'process_guid' => $process->guid, 'name' => $process->name, 'project_type' => $project_type ])) { + if ($glpiprocess->add([ + 'process_guid' => $process->guid, + 'name' => $process->name, + 'project_type' => $project_type, + ])) { + $glpiprocess->updateProcessCategory($process->category_guid); // and add main task category for this process $glpiprocess->addTaskCategory( $pmMainTaskCat ); } @@ -419,6 +427,26 @@ class PluginProcessmakerProcess extends CommonDBTM { } } + + /** + * Summary of updateProcessCategory + * Update Process category for current process, only if needed (i.e. name has changed) + * @return boolean true if update is done, false otherwise + */ + function updateProcessCategory($category_guid) { + global $PM_DB; + if ($category_guid) { + $processCategories = new PluginProcessmakerProcessCategory(); + $processCategories->getFromDBByCrit(["category_guid" => $category_guid]); + if ($processCategories) { + return $this->update([ + 'id' => $this->getID(), + 'plugin_processmaker_processcategories_id' => $processCategories->fields['id'] + ]); + } + } + return false; + } /** * Summary of updateTaskCategory @@ -648,6 +676,14 @@ class PluginProcessmakerProcess extends CommonDBTM { 'massiveaction' => true, 'datatype' => 'number' ]; + $tab[] = [ + 'id' => '22', + 'table' => 'glpi_plugin_processmaker_processcategories', + 'field' => 'name', + 'name' => __('Process category'), + 'massiveaction' => false, + 'datatype' => 'dropdown', + ]; return $tab; } @@ -749,6 +785,11 @@ class PluginProcessmakerProcess extends CommonDBTM { echo $this->fields["process_guid"]; echo ""; + echo ""; + echo "".__('Process category', 'processmaker').""; + echo Dropdown::getDropdownName('glpi_plugin_processmaker_processcategories', $this->fields["plugin_processmaker_processcategories_id"]); + echo ""; + echo ""; echo "".__('Active').""; Dropdown::showYesNo("is_active", $this->fields["is_active"]); diff --git a/inc/processCategory.class.php b/inc/processCategory.class.php new file mode 100644 index 0000000..e8feb2f --- /dev/null +++ b/inc/processCategory.class.php @@ -0,0 +1,58 @@ +. +-------------------------------------------------------------------------- + */ +/** + * PluginProcessmakerTaskCategory short summary. + * + * PluginProcessmakerTaskCategory description. + * + * @version 1.0 + * @author MoronO + */ + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access directly to this file"); +} + + +class PluginProcessmakerProcessCategory extends CommonDBTM +{ + static function refreshCategories() { + global $PM_DB; + + $processCategories = new self; + foreach($PM_DB->request('PROCESS_CATEGORY') as $data) { + if (!$processCategories->getFromDBByCrit(["category_guid" => $data['CATEGORY_UID']])) { + $processCategories->add([ + 'name' => $data['CATEGORY_NAME'], + 'category_guid' => $data['CATEGORY_UID'] + ]); + } + } + } + +} diff --git a/inc/process_profile.class.php b/inc/process_profile.class.php index 4b75b4b..db8d56d 100644 --- a/inc/process_profile.class.php +++ b/inc/process_profile.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/processmaker.class.php b/inc/processmaker.class.php index 5f5a72e..572cd66 100644 --- a/inc/processmaker.class.php +++ b/inc/processmaker.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -167,13 +167,13 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { * @param mixed $txtForFollowup * @param integer $users_id optional, if null will uses logged-in user */ - public function addItemFollowup($itemtype, $itemId, $txtForFollowup, $users_id = null) { + public function addItemFollowup($itemtype, $itemId, $txtForFollowup, $cases_id, $tasks_id, $users_id = null) { global $DB; $fu = new ITILFollowup(); $input = $fu->fields; - if (isset($txtForFollowup['GLPI_ITEM_FOLLOWUP_CONTENT']) && $txtForFollowup['GLPI_ITEM_FOLLOWUP_CONTENT'] != "") { - $input['content'] = $DB->escape($txtForFollowup['GLPI_ITEM_FOLLOWUP_CONTENT']); - } + + $input['content'] = $DB->escape($txtForFollowup['GLPI_ITEM_FOLLOWUP_CONTENT'] . ""); + if (isset($txtForFollowup['GLPI_ITEM_FOLLOWUP_IS_PRIVATE']) && $txtForFollowup['GLPI_ITEM_FOLLOWUP_IS_PRIVATE'] != "") { $input['is_private'] = $txtForFollowup['GLPI_ITEM_FOLLOWUP_IS_PRIVATE']; } @@ -659,16 +659,18 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { */ function cancelCase($caseUid) { try { - $pmCaseInfo = $this->getCaseInfo($caseUid); - if ($pmCaseInfo->status_code == 0) { - foreach ($pmCaseInfo->currentUsers as $pmUser) { - $pmCancelTask = $this->cancelTask($caseUid, $pmUser->delIndex, $pmUser->userId); - if ($pmCancelTask->status_code != 0) { - return $pmCancelTask; - } - } - } - return $pmCancelTask; + $pmCaseInfo = $this->getCaseInfo($caseUid); + if ($pmCaseInfo->status_code == 0) { + if (count($pmCaseInfo->currentUsers) > 1) { + $pmCancelTask = $this->cancelTask($caseUid, null, null); + } else { + $pmCancelTask = $this->cancelTask($caseUid, $pmCaseInfo->currentUsers[0]->delIndex, PluginProcessmakerUser::getPMUserId($_SESSION['glpiID'])); + if ($pmCancelTask->status_code != 0) { + return $pmCancelTask; + } + } + } + return $pmCancelTask; } catch (Exception $e) { Toolbox::logDebug($e); return false; @@ -1636,7 +1638,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { // here we create a fake task that will be used to store the creator of the case // this is due for traceability only - $PM_SOAP->add1stTask($myCase->getID(), $myCase->fields['itemtype'], $myCase->fields['items_id'], $caseInfo, [ 'notif' => false]); // no notif + $PM_SOAP->add1stTask($myCase->getID(), $myCase->fields['itemtype'], $myCase->fields['items_id'], $caseInfo, ['notif' => false, 'userId' => Session::getLoginUserID()]); // no notif // before routing, send items_id and itemtype // as this information was not available at case creation @@ -1766,6 +1768,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { * 'txtTaskContent' => '', * 'start_date' => '', * 'end_date' => '', + * 'reminder' => '', * 'notif' => true * @return */ @@ -1853,7 +1856,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { $input['content'] .= "##processmakercase.url##"; $input['is_private'] = 0; - $input['actiontime'] = 0; + //$input['actiontime'] = 0; $input['state'] = Planning::TODO; // == TO_DO $input['users_id_tech'] = 0; // by default as it can't be empty if ($techId) { @@ -1862,13 +1865,13 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { $input['groups_id_tech'] = $groups_id_tech['id']; } - if ($options['reminder'] != '' && $techId) { - $input['_planningrecall'] = ['before_time' => $options['reminder'], - 'itemtype' => get_class($glpi_task), - 'items_id' => '', - 'users_id' => $techId, - 'field' => 'begin']; - } + //if ($options['reminder'] != '' && $techId) { + // $input['_planningrecall'] = ['before_time' => $options['reminder'], + // 'itemtype' => get_class($glpi_task), + // 'items_id' => '', + // 'users_id' => $techId, + // 'field' => 'begin']; + //} $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet as the PluginProcessmakerTask is not yet added to DB $glpi_task->add(Toolbox::addslashes_deep($input)); @@ -1881,12 +1884,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { if ($glpi_task->getId() > 0) { // stores link to task in DB - //$tmp = new PluginProcessmakerTask($glpi_task->getType()); - //$tmp->add([ 'itemtype' => $glpi_task->getType(), - // 'items_id' => $glpi_task->getId(), - // 'plugin_processmaker_cases_id' => $cases_id, - // 'del_index' => $delIndex - // ], [], false); + // can't use a GLPI framework object as PluginProcessmakerTask::getFromDB() has been overloaded $DB->insert('glpi_plugin_processmaker_tasks', [ 'items_id' => $glpi_task->getId(), @@ -1896,10 +1894,26 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { 'del_index' => $delIndex, 'del_thread' => $delThread ]); - //$query = "INSERT INTO glpi_plugin_processmaker_tasks (items_id, itemtype, plugin_processmaker_cases_id, plugin_processmaker_taskcategories_id, del_index, del_thread) - // VALUES ({$glpi_task->getId()}, '{$glpi_task->getType()}', $cases_id, {$pmtaskcat->fields['id']}, $delIndex, $delThread);"; - //$DB->query($query); - //} + $pmTaskId = $DB->insertId(); + + // check if there is a recall reminder from the $pm_taskcat + $before_time = $pmtaskcat->fields['before_time']; + $after_time = $pmtaskcat->fields['after_time']; + if ($options['reminder'] != '') { + $before_time = $options['reminder']; + } + if ($before_time != PluginProcessmakerTaskCategory::REMINDER_NONE || $after_time != PluginProcessmakerTaskCategory::REMINDER_NONE) { + // then add a PluginProcessmakerTaskrecall object in DB + $when = ($before_time > PluginProcessmakerTaskCategory::REMINDER_NONE ? date("Y-m-d H:i:s", strtotime($input['begin']) - $before_time) : date("Y-m-d H:i:s", strtotime($input['end']) + $after_time)); + $pr = new PluginProcessmakerTaskrecall(); + $pr->add([ + 'plugin_processmaker_tasks_id' => $pmTaskId, + 'users_id' => $pmtaskcat->fields['users_id'], + 'before_time' => $before_time, + 'after_time' => $after_time, + 'when' => $when + ]); + } // send notification if needed for new task as now we have the PluginProcessmakerTask in the DB $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState($options['notif']); @@ -1965,7 +1979,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { $start_date = new DateTime($_SESSION["glpi_currenttime"]); $official_date_time = $_SESSION["glpi_currenttime"]; $_SESSION["glpi_currenttime"] = $start_date->sub(new DateInterval("PT1S"))->format("Y-m-d H:i:s"); - $userId = $options['userId'] ? $options['userId'] : Session::getLoginUserID(); + $userId = $options['userId']; unset($options['userId']); // unset it as it's not in the options of addTask $this->addTask($cases_id, @@ -2239,7 +2253,6 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { $pm_task->sendNotification('task_done', $glpi_task, $hostItem); PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif); - // restore current glpi time $_SESSION["glpi_currenttime"] = $saved_date_time; @@ -2452,26 +2465,114 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { $tmpCase->getFromDB($pmTask->fields['plugin_processmaker_cases_id']); $urlLink = $tmpCase->getLinkURL().'&forcetab=PluginProcessmakerTask$'.$pmTask->fields['items_id']; + if ($pmTask->fields['del_thread_status'] != PluginProcessmakerTask::CLOSED) { + if ($params['item']->fields['state'] != Planning::INFO) { + echo Html::scriptBlock(" + function $taskJSId(ev) { + //debugger; + if ($(ev.target).parent('.read_more').length == 0) { + $('div[data-items-id=\"$dataItemId\"]').width('100%'); + $('div[data-items-id=\"$dataItemId\"]').find('.edit_content').width('100%').css({ 'background-color': 'white', 'padding': '5px 0', 'text-align': 'center'}) + $('div[data-items-id=\"$dataItemId\"]').find('.read-only-content').hide(); + $('div[data-items-id=\"$dataItemId\"]').find('.edit_content').show().load('/plugins/processmaker/ajax/task.php', + {'cases_id': {$pmTask->fields['plugin_processmaker_cases_id']}, + 'tabnum': {$pmTask->fields['items_id']}}); + $('div[data-items-id=\"$dataItemId\"] .close-edit-content').show().toggleClass('d-none') + .click(function() { + $(this).hide(); + $('div[data-items-id=\"$dataItemId\"] .edit_content').empty().hide(); + $('div[data-items-id=\"$dataItemId\"] .read-only-content').show(); + $('div[data-items-id=\"$dataItemId\"]').width(''); + }); + } + }; +//debugger; + $('div[data-items-id=\"$dataItemId\"]').find('.read-only-content').parent().append('
'); + $('div[data-items-id=\"$dataItemId\"]').find('.edit_content').hide(); + //$('div[data-items-id=\"$dataItemId\"]').find('.timeline-header .timeline-item-buttons').append('
'); + $('div[data-items-id=\"$dataItemId\"]').find('.timeline-header .close-edit-content').appendTo('div[data-items-id=\"$dataItemId\"] .timeline-item-buttons'); + $('div[data-items-id=\"$dataItemId\"]').find('.close-edit-content').hide(); + $('div[data-items-id=\"$dataItemId\"]').find('.text-content').on('click', $taskJSId).css('cursor', 'pointer'); + $('div[data-items-id=\"$dataItemId\"]').find('.read_more').css('cursor', 'auto'); + $('tr[id=\"$taskJSId\"]').children().on('click', $taskJSId).css('cursor', 'pointer'); + $(function() { + $('div[data-items-id=\"$dataItemId\"]').find('.timeline-item-buttons').prepend( + '".str_replace("'", "\\'", $tmpCase->fields['name'])."' + + 'fields['id']}\">{$tmpCase->fields['id']}' + + '' + ); + }); + "); + } else { + echo Html::scriptBlock(" + function $taskJSId(ev) { + //debugger; + if ($(ev.target).parent('.read_more').length == 0) { + document.location='$urlLink'; + } + }; + $('#$taskJSId').find('.item-content').on('click', $taskJSId).css('cursor', 'pointer'); + $('#$taskJSId').find('.read_more').css('cursor', 'auto'); + $('tr[id=\"$taskJSId\"]').children().on('click', $taskJSId).css('cursor', 'pointer'); + $(function() { + $('#$taskJSId').find('.displayed_content span.state').parent().append( + '".str_replace("'", "\\'", $tmpCase->fields['name'])."' + + 'fields['id']}\">{$tmpCase->fields['id']}' + + '' + ); + }); + "); + } + } else { + echo Html::scriptBlock(" + function $taskJSId(ev) { + if ($(ev.target).parent('.read_more').length == 0) { + document.location='$urlLink'; + } + }; + $('div[data-items-id=\"$dataItemId\"]').find('.text-content').on('click', $taskJSId).css('cursor', 'pointer'); + $('div[data-items-id=\"$dataItemId\"]').find('.read_more').css('cursor', 'auto'); + $('tr[id=\"$taskJSId\"]').children().on('click', $taskJSId).css('cursor', 'pointer'); + $(function() { + $('div[data-items-id=\"$dataItemId\"]').find('.timeline-item-buttons').prepend( + '".str_replace("'", "\\'", $tmpCase->fields['name'])."' + + 'fields['id']}\">{$tmpCase->fields['id']}' + + '' + ); + }); + //$('#$taskJSId').find('.displayed_content > div').last().html( + // $('#$taskJSId').find('.displayed_content > div').last().html().replace(/(.*?)(
.*)/, '$1$2') + //); + "); + } + //will open all todo tasks when created within last 30 seconds + if ((strtotime($pmTask->fields['date_creation']) > strtotime("-30 second") || strtotime($pmTask->fields['date_mod']) > strtotime("-30 second")) + && (Session::getLoginUserID() === $pmTask->fields['users_id_tech'] || !empty(Group_User::getGroupUsers($pmTask->fields['groups_id_tech'], ['users_id' => Session::getLoginUserID()]))) + && $params['item']->fields['state'] == Planning::TODO) { + echo Html::scriptBlock(" + $('div[data-items-id=\"$dataItemId\"]').width('100%'); + $('div[data-items-id=\"$dataItemId\"]').find('.edit_content').width('100%').css({ 'background-color': 'white', 'padding': '5px 0', 'text-align': 'center'}) + $('div[data-items-id=\"$dataItemId\"]').find('.read-only-content').hide(); + $('div[data-items-id=\"$dataItemId\"]').find('.edit_content').show().load('/plugins/processmaker/ajax/task.php', + {'cases_id': {$pmTask->fields['plugin_processmaker_cases_id']}, + 'tabnum': {$pmTask->fields['items_id']}}, function() { + $('div[data-items-id=\"$dataItemId\"]')[0].scrollIntoView({ behavior: 'smooth', block: 'start' }); + }); + $('div[data-items-id=\"$dataItemId\"] .close-edit-content').show().toggleClass('d-none') + .click(function() { + $(this).hide(); + $('div[data-items-id=\"$dataItemId\"] .edit_content').empty().hide(); + $('div[data-items-id=\"$dataItemId\"] .read-only-content').show(); + $('div[data-items-id=\"$dataItemId\"]').width(''); + }); + "); + } + // will add a class to the div.h_content echo Html::scriptBlock(" - function $taskJSId(ev) { - if ($(ev.target).parent('.read_more').length == 0) { - document.location='$urlLink'; - } - }; - $('div[data-items-id=\"$dataItemId\"]').find('.text-content').on('click', $taskJSId).css('cursor', 'pointer'); - $('div[data-items-id=\"$dataItemId\"]').find('.read_more').css('cursor', 'auto'); - $('tr[id=\"$taskJSId\"]').children().on('click', $taskJSId).css('cursor', 'pointer'); - $(function() { - $('div[data-items-id=\"$dataItemId\"]').find('.timeline-item-buttons').prepend( - '".str_replace("'", "\\'", $tmpCase->fields['name'])."' + - 'fields['id']}\">{$tmpCase->fields['id']}' + - '' - ); - }); - //$('#$taskJSId').find('.displayed_content > div').last().html( - // $('#$taskJSId').find('.displayed_content > div').last().html().replace(/(.*?)(
.*)/, '$1$2') - //); - "); + //$('div[data-items-id=\"$dataItemId\"]').removeClass('ITILTask'); + $('div[data-items-id=\"$dataItemId\"]').addClass('Case-".$pmTask->fields['plugin_processmaker_cases_id']."'); + "); + // in order to set NavigationList Session::initNavigateListItems('PluginProcessmakerCase', //TRANS : %1$s is the itemtype name, @@ -2483,6 +2584,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { } static function show_in_timeline_processmaker($params) { + global $CFG_GLPI; foreach($params['timeline'] as $key => $timelineObject) { if (is_subclass_of($timelineObject['type'], 'CommonITILTask')) { $pmTask = new PluginProcessmakerTask($timelineObject['type']); @@ -2531,8 +2633,137 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { } } } + //$itemtype = $params['item']->getType(); + // if (in_array($itemtype, ['Ticket', 'Problem', 'Change']) + // && $params['item']->getID() + // && Session::getCurrentInterface() == "central") { + // $rand = rand(); + //$status = $params['item']->fields['status']; + //if ($status !== CommonITILObject::CLOSED && $status !== CommonITILObject::SOLVED) { + // $user = User::getById(Session::getLoginUserID()); + // $btnLayout = $user->fields["timeline_action_btn_layout"]; + // if ($btnLayout == null) { + // $btnLayout = 0; + // } + // echo Html::scriptBlock(" + // if (window.jQuery != undefined) { + // $(document).ready(function() { + // function newCasebutton(){ + // $('.timeline-buttons .main-actions').hide(); + // $('#right-actions').hide(); + // $(document).on('click', '#new-itilobject-form .close-new-case-form', function() { + // $('#itil-footer .main-actions').show(); + // $('#right-actions').show(); + // }); + // } + // if ($btnLayout) { + // $('.timeline-buttons .main-actions').append(''); + // } + // else { + // $('.timeline-buttons .main-actions .dropdown-menu').append(\"
  • ".__('Add a case', 'processmaker')."
  • \"); + // } + // $('.timeline-buttons .main-actions .newCase').css('background-color', '#4185F4'); + // $('.timeline-buttons .main-actions .newCase').on('click', newCasebutton).css('cursor', 'pointer'); + // $('#new-itilobject-form').append('
    ') + // $('#new-CaseForm-block').load('/plugins/processmaker/ajax/case.php', {'items_id': {$params['item']->getID()}, 'itemtype': '{$params['item']->getType()}'}); + // }) + // };"); + //} + //
  • + // + + //// will add filter for each cases in this object + //foreach (getAllDataFromTable(PluginProcessmakerCase::GetTable(), ['itemtype' => $itemtype, 'items_id' => $params['item']->getID()]) as $row) { + // echo Html::scriptBlock(" + // if (window.jQuery != undefined) { + // $(document).ready(function() { + // $('.filter-timeline div.ITILTask').parents('li').before('
  • '); + // })};"); + //} + //echo Html::scriptBlock(" + // if (window.jQuery != undefined) { + // $(document).ready(function() { + // $('.filter-timeline div.list-group').prepend('
  • ') + // $('.filter-timeline #timeline-filter-filter-all').on('click', function (e) { + // $('.filter-timeline li').each(function () { + // if ($(this).find('.FilterAll').length == 0 + // && $(this).find('.Log').length == 0 + // && $(this).find('input[type=checkbox]').prop('checked') != $('#timeline-filter-filter-all').prop('checked')) { + // $(this).find('input[type=checkbox]').click(); + // } + // }) + // }) + // }) + // }"); + //} } + /** + * Summary of post_show_item_processmaker + * @param mixed $params + */ + public static function post_show_item_processmaker($params) { + $itemtype = $params['item']->getType(); + if (in_array($itemtype, ['Ticket', 'Problem', 'Change']) + && $params['item']->getID() + && Session::getCurrentInterface() == "central") { + $status = $params['item']->fields['status']; + if ($status !== CommonITILObject::CLOSED && $status !== CommonITILObject::SOLVED) { + $user = User::getById(Session::getLoginUserID()); + $btnLayout = $user->fields["timeline_action_btn_layout"]; + if ($btnLayout == null) { + $btnLayout = 0; + } + echo Html::scriptBlock(" + $(document).ready(function() { + function newCasebutton(){ + $('.timeline-buttons .main-actions').hide(); + $('#right-actions').hide(); + $(document).on('click', '#new-itilobject-form .close-new-case-form', function() { + $('#itil-footer .main-actions').show(); + $('#right-actions').show(); + }); + } + if ($btnLayout) { + $('.timeline-buttons .main-actions').append(''); + } + else { + $('.timeline-buttons .main-actions .dropdown-menu').append(\"
  • ".__('Add a case', 'processmaker')."
  • \"); + } + $('.timeline-buttons .main-actions .newCase').css('background-color', '#4185F4'); + $('.timeline-buttons .main-actions .newCase').on('click', newCasebutton).css('cursor', 'pointer'); + $('#new-itilobject-form').append('
    ') + $('#new-CaseForm-block').load('/plugins/processmaker/ajax/case.php', {'items_id': {$params['item']->getID()}, 'itemtype': '{$params['item']->getType()}'}); + }) + ;"); + } + // will add filter for each cases in this object + foreach (getAllDataFromTable(PluginProcessmakerCase::GetTable(), ['itemtype' => $itemtype, 'items_id' => $params['item']->getID()]) as $row) { + echo Html::scriptBlock(" + if (window.jQuery != undefined) { + $(document).ready(function() { + $('.filter-timeline div.ITILTask').parents('li').before('
  • '); + })};"); + } + echo Html::scriptBlock(" + if (window.jQuery != undefined) { + $(document).ready(function() { + $('.filter-timeline div.list-group').prepend('
  • ') + $('.filter-timeline #timeline-filter-filter-all').on('click', function (e) { + $('.filter-timeline li').each(function () { + if ($(this).find('.FilterAll').length == 0 + && $(this).find('.Log').length == 0 + && $(this).find('input[type=checkbox]').prop('checked') != $('#timeline-filter-filter-all').prop('checked')) { + $(this).find('input[type=checkbox]').click(); + } + }) + }) + }) + }"); + } + } + + /** * Summary of getItemUsers * returns an array of glpi ids and pm ids for each user type assigned to given ticket @@ -2748,9 +2979,9 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { //if ($pmtask->getFromDBByQuery("WHERE itemtype = '$pmtask_itemtype' AND items_id = $pmtask_items_id")) { if ($pmtask->getFromDBByRequest($restrict)) { - if (!in_array("tasks", $item->tag_descriptions)) { - $item->html_tags[] = "tasks"; // to force GLPI to keep the below HTML tags, otherwise it will apply a Html::entities_deep() to the task.description - } + //if (!in_array("tasks", $item->tag_descriptions)) { + // $item->html_tags[] = "tasks"; // to force GLPI to keep the below HTML tags, otherwise it will apply a Html::entities_deep() to the task.description + //} $task['##task.description##'] = str_replace('##processmaker.taskcomment##', $task['##task.categorycomment##'], $task['##task.description##']); $task['##task.description##'] = nl2br($task['##task.description##']); @@ -2960,6 +3191,9 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { ], [], true); + if ($caseInfo->currentUsers[0]->userId == "") { // in case the task is "to be claimed" + $users_id = 0; + } $this->add1stTask($locCase->getID(), $itemtype, $items_id, $caseInfo, ['userId' => $users_id]); } @@ -3209,7 +3443,7 @@ class PluginProcessmakerProcessmaker extends CommonDBTM { // create a followup if requested if ($createFollowup) { // && $itemtype == 'Ticket') { - $this->addItemFollowup($itemtype, $items_id, $casevariablevalues); + $this->addItemFollowup($itemtype, $items_id, $casevariablevalues, $myCase->getID(), $glpi_task->getID()); } if ($txtItemTitle != '') { diff --git a/inc/profile.class.php b/inc/profile.class.php index 30d085e..f613b9f 100644 --- a/inc/profile.class.php +++ b/inc/profile.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/selfservicedraft.class.php b/inc/selfservicedraft.class.php index 45d26ec..015ab32 100644 --- a/inc/selfservicedraft.class.php +++ b/inc/selfservicedraft.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/inc/task.class.php b/inc/task.class.php index 26aca76..56e403f 100644 --- a/inc/task.class.php +++ b/inc/task.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -35,10 +35,21 @@ along with this plugin. If not, see . */ class PluginProcessmakerTask extends CommonITILTask { + private $users_id_sender; + private $itemtype; + function __construct($itemtype = 'TicketTask') { parent::__construct(); - $this->itemtype = $itemtype; + $this->itemtype = $itemtype; + $this->users_id_sender = 0; + } + + function getSender() { + return $this->users_id_sender; + } + function setSender($users_id) { + $this->users_id_sender = $users_id; } @@ -66,7 +77,6 @@ class PluginProcessmakerTask extends CommonITILTask function getFromDB($items_id) { global $DB; - //if ($this->getFromDBByQuery(" WHERE itemtype='".$this->itemtype."' AND items_id=$items_id;" )) { if ($this->getFromDBByRequest([ 'WHERE' => [ 'itemtype' => $this->itemtype, @@ -137,7 +147,6 @@ class PluginProcessmakerTask extends CommonITILTask $events = []; if (isset($params['start'])) { - $params['begin'] = $params['start']; //'2000-01-01 00:00:00'; if ($params['type'] == 'group') { $params['who_group'] = $params['who']; $params['whogroup'] = $params['who']; @@ -188,7 +197,7 @@ class PluginProcessmakerTask extends CommonITILTask $caseInfo = $case->getCaseInfo(); - if (property_exists($caseInfo, 'currentUsers')) { + if (property_exists($caseInfo, 'currentUsers') && $caseInfo->caseStatus != PluginProcessmakerCase::CANCELLED) { $dbu = new DbUtils; $GLPICurrentPMUserId = PluginProcessmakerUser::getPMUserId(Session::getLoginUserID()); @@ -377,7 +386,7 @@ class PluginProcessmakerTask extends CommonITILTask $used_users = []; - $used_users[] = $current_assigned_user; + //$used_users[] = $current_assigned_user; // not set to be able to alert when trying to re-assigned to the same user if (array_key_exists($currentUser->taskId, $prevent_assign)) { if (!is_array($prevent_assign[$currentUser->taskId])) { $prevent_assign[$currentUser->taskId] = [$prevent_assign[$currentUser->taskId]]; @@ -401,7 +410,7 @@ class PluginProcessmakerTask extends CommonITILTask taskGuid : '{$currentUser->taskId}', delIndex : {$task[$tabnum]['del_index']}, delThread : {$currentUser->delThread}, -// used : [".join(',', array_unique($used_users))."] // not set to be able to alert when trying to re-assigned to the same user + used : [".join(',', array_unique($used_users))."] }"; echo html::scriptBlock("$('#divUsers-{$task[$tabnum]['del_index']}-{$rand}').load('".Plugin::getWebDir('processmaker')."/ajax/task_users.php', $data);"); } @@ -470,7 +479,7 @@ class PluginProcessmakerTask extends CommonITILTask // search if at least one active notification is existing for that pm task with that event 'task_update_'.$glpi_task->fields['taskcategories_id'] $res = PluginProcessmakerNotificationTargetTask::getNotifications($type, $task->fields['taskcategories_id'], $item->fields['entities_id']); if ($res['notifications'] && count($res['notifications']) > 0) { - NotificationEvent::raiseEvent($res['event'], + return NotificationEvent::raiseEvent($res['event'], $this, ['plugin_processmaker_cases_id' => $this->fields['plugin_processmaker_cases_id'], 'itemtype' => $item->getType(), @@ -482,7 +491,7 @@ class PluginProcessmakerTask extends CommonITILTask 'obj' => $item ]); } else { - NotificationEvent::raiseEvent(PluginProcessmakerNotificationTargetTask::getDefaultGLPIEvents($type), + return NotificationEvent::raiseEvent(PluginProcessmakerNotificationTargetTask::getDefaultGLPIEvents($type), $item, ['plugin_processmaker_cases_id' => $this->fields['plugin_processmaker_cases_id'], 'itemtype' => $item->getType(), diff --git a/inc/taskalert.class.php b/inc/taskalert.class.php new file mode 100644 index 0000000..d04b799 --- /dev/null +++ b/inc/taskalert.class.php @@ -0,0 +1,30 @@ +. +-------------------------------------------------------------------------- + */ +class PluginProcessmakerTaskalert extends CommonDBTM { + +} diff --git a/inc/taskcategory.class.php b/inc/taskcategory.class.php index 5203987..68e38c6 100644 --- a/inc/taskcategory.class.php +++ b/inc/taskcategory.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -42,6 +42,9 @@ if (!defined('GLPI_ROOT')) { class PluginProcessmakerTaskCategory extends CommonDBTM { + const REMINDER_NONE = -10; + const REMINDER_STOP = -20; + static $rightname = 'taskcategory'; function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { @@ -57,6 +60,46 @@ class PluginProcessmakerTaskCategory extends CommonDBTM } + static function getAllAfterReminders() { + $possible_values = []; + $possible_values[self::REMINDER_NONE] = __('None'); + + $min_values = [15, 30]; + foreach ($min_values as $val) { + $possible_values[$val * MINUTE_TIMESTAMP] = sprintf(_n('%d minute', '%d minutes', $val), $val); + } + + $h_values = [1, 2, 4, 8, 12]; + foreach ($h_values as $val) { + $possible_values[$val * HOUR_TIMESTAMP] = sprintf(_n('%d hour', '%d hours', $val), $val); + } + $d_values = [1, 2, 4, 6]; + foreach ($d_values as $val) { + $possible_values[$val * DAY_TIMESTAMP] = sprintf(_n('%d day', '%d days', $val), $val); + } + $w_values = [1, 2, 3]; + foreach ($w_values as $val) { + $possible_values[$val * WEEK_TIMESTAMP] = sprintf(_n('%d week', '%d weeks', $val), $val); + } + $m_values = [1, 2]; + foreach ($m_values as $val) { + $possible_values[$val * MONTH_TIMESTAMP] = sprintf(_n('%d month', '%d months', $val), $val); + } + + return $possible_values; + } + + + static function getAfterReminder($value) { + $arr = self::getAllAfterReminders(); + if (array_key_exists($value, $arr)) { + return $arr[$value]; + } else { + return null; + } + } + + static function displayTabContentForProcess(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { global $DB, $CFG_GLPI; @@ -272,6 +315,7 @@ class PluginProcessmakerTaskCategory extends CommonDBTM echo Dropdown::getYesNo($taskCat['is_subprocess']); echo ""; + echo "" . __('Re-assign reason setting', 'processmaker') . ""; echo ""; echo "" . __('Re-assign reason is mandatory', 'processmaker') . ""; echo ""; @@ -291,12 +335,53 @@ class PluginProcessmakerTaskCategory extends CommonDBTM .$elements[self::inheritedReAssignReason($taskCat['is_reassignreason_mandatory'], $taskCat['gppp_is_reassignreason_mandatory'])] ."
    "; } + echo ""; + + echo "" . __('Reminder settings', 'processmaker') . ""; + echo ""; + echo "" . __('Before task (once)', 'processmaker'); + echo " "; + echo " "; + Html::showToolTip(__('Can be overridden by GLPI_ITEM_TASK_REMINDER', 'processmaker'), [ + 'link' => 'https://github.com/tomolimo/processmaker/wiki/Case-Variables#glpi_item_task_reminder', + 'linktarget' => '_blank' + ]); + echo ""; + echo ""; + Dropdown::showFromArray('before_time', self::getAllBeforeReminders(), [ + 'value' => $pmtaskcat->fields['before_time'] + ]); echo ""; + echo "" . __('Outdated task (every)', 'processmaker') . ""; + echo ""; + Dropdown::showFromArray('after_time', self::getAllAfterReminders(), [ + 'value' => $pmtaskcat->fields['after_time'], + ]); + echo ""; + echo ""; + + echo "" . __('Sender (default: GLPI)', 'processmaker') . ""; + echo ""; + User::dropdown(['name' => 'users_id', + 'display_emptychoice' => true, + 'right' => 'all', + 'value' => $pmtaskcat->fields['users_id']]); + echo ""; $pmtaskcat->showFormButtons(['candel'=>false]); } + + function prepareInputForUpdate($input) { + if (isset($input['_planningrecall']['before_time'])) { + $input['reminder_recall_time'] = $input['_planningrecall']['before_time']; + unset($input['_planningrecall']); + } + return $input; + } + + /** * Summary of displayTabContentForItem * @param CommonGLPI $item @@ -364,9 +449,6 @@ class PluginProcessmakerTaskCategory extends CommonDBTM 'taskcategories_id' => $catid ] ); - //$query = "SELECT * - // FROM `".$this->getTable()."` - // WHERE `taskcategories_id` = $catid"; if ($res) { if ($res->numrows() != 1) { return false; @@ -376,69 +458,247 @@ class PluginProcessmakerTaskCategory extends CommonDBTM return true; } } - //if ($result = $DB->query($query)) { - // if ($DB->numrows($result) != 1) { - // return false; - // } - // $this->fields = $DB->fetch_assoc($result); - // if (is_array($this->fields) && count($this->fields)) { - // return true; - // } - //} return false; } - ///** - // * Summary of dropdown - // * @param mixed $options - // * @return mixed - // */ - //static function dropdown($options=array()) { - // global $CFG_GLPI; - // if (isset($options['value'])) { - // $that = new self; - // $that->getFromDB($options['value']); - // $options['value'] = $that->fields['taskcategories_id']; - // } + /** + * summary of cronInfo + * Gives localized information about 1 cron task + * @param $name of the task + * @return array of strings + */ + static function cronInfo ($name) { + switch ($name) { + case 'pmreminders' : + return ['description' => __('To send auto-reminders and overdue reminders.', 'processmaker')]; + } + return []; + } - // $options['url'] = Plugin::getWebDir('processmaker').'/ajax/dropdownTaskcategories.php'; - // return Dropdown::show( 'TaskCategory', $options ); + /** + * Summary of cronPMReminders + * @param mixed $crontask + * @return int + */ + static function cronPMReminders ($crontask = null) { + global $DB, $CFG_GLPI, $PM_SOAP; + + if (!$CFG_GLPI["use_notifications"]) { + return 0; + } - //} + $pmconfig = $PM_SOAP->config; - ///** - // * Execute the query to select ProcesssmakerTaskcategories - // * - // * @param $count true if execute an count(*), - // * @param $search pattern - // * - // * @return mysql result set. - // **/ - //static function getSqlSearchResult ($count=true, $search='') { - // global $DB, $CFG_GLPI; + $cron_status = 0; + $iterator = $DB->request([ + 'SELECT' => ['glpi_plugin_processmaker_taskrecalls.*', + 'glpi_plugin_processmaker_tasks.itemtype as gppt-itemtype', + 'glpi_plugin_processmaker_tasks.items_id as gppt-items_id', + 'glpi_plugin_processmaker_tasks.plugin_processmaker_cases_id as gppt-cases_id', + 'glpi_plugin_processmaker_cases.id as gppc-id', + 'glpi_plugin_processmaker_cases.name as gppc-name', + 'glpi_plugin_processmaker_cases.case_status as gppc-case_status'], + 'DISTINCT' => true, + 'FROM' => 'glpi_plugin_processmaker_taskrecalls', + 'LEFT JOIN' => [ + 'glpi_plugin_processmaker_taskalerts' => [ + 'ON' => [ + 'glpi_plugin_processmaker_taskrecalls' => 'id', + 'glpi_plugin_processmaker_taskalerts' => 'plugin_processmaker_taskrecalls_id', + ] + ], + 'glpi_plugin_processmaker_tasks' => [ + 'ON' => [ + 'glpi_plugin_processmaker_tasks' => 'id', + 'glpi_plugin_processmaker_taskrecalls' => 'plugin_processmaker_tasks_id' + ] + ], + 'glpi_plugin_processmaker_cases' => [ + 'ON' => [ + 'glpi_plugin_processmaker_cases' => 'id', + 'glpi_plugin_processmaker_tasks' => 'plugin_processmaker_cases_id' + ] + ], + ], + 'WHERE' => [ + 'NOT' => ['glpi_plugin_processmaker_taskrecalls.when' => null], + 'glpi_plugin_processmaker_taskrecalls.when' => ['<', new \QueryExpression('NOW()')], + 'glpi_plugin_processmaker_tasks.del_thread_status' => PluginProcessmakerTask::OPEN, + 'OR' => [ + ['glpi_plugin_processmaker_taskalerts.date' => null], + ['glpi_plugin_processmaker_taskalerts.date' => ['<', new \QueryExpression($DB->quoteName('glpi_plugin_processmaker_taskrecalls.when'))]]] + ] + ]); - // $orderby = ''; + foreach ($iterator as $data) { + if ($data['gppc-case_status'] == PluginProcessmakerCase::CANCELLED) { + PluginProcessmakerCase::deleteReminders($data['gppc-id']); + continue; + } + $pm_task = new PluginProcessmakerTask($data['gppt-itemtype']); + $pm_task->getFromDB($data['gppt-items_id']); - // $where = ' WHERE glpi_plugin_processmaker_taskcategories.is_active=1 '; + // init sender + $pm_task->setSender($data['users_id']); - // $join = ' LEFT JOIN glpi_taskcategories ON glpi_taskcategories.id = glpi_plugin_processmaker_taskcategories.taskcategories_id'; + $glpi_task = new $data['gppt-itemtype']; + $glpi_task->fields = $pm_task->fields; - // if ($count) { - // $fields = " COUNT(DISTINCT glpi_plugin_processmaker_taskcategories.id) AS cpt "; - // } else { - // $fields = " DISTINCT glpi_taskcategories.id, glpi_taskcategories.completename AS name "; - // $orderby = " ORDER BY glpi_taskcategories.completename ASC"; - // } + $itemtype = $pm_task->getItilObjectItemType(); + $glpi_item = new $itemtype; + $glpi_item->getFromDB($pm_task->fields[$glpi_item->getForeignKeyField()]); - // if (strlen($search)>0 && $search!=$CFG_GLPI["ajax_wildcard"]) { - // $where .= " AND (glpi_taskcategories.completename $search - // OR glpi_taskcategories.comment $search) "; - // } + $add_alert = false; // by default + $new_when = 0; // by default + if ($data['before_time'] >= 0) { + // then send task "before reminder" + if ($pm_task->sendNotification('task_reminder', $glpi_task, $glpi_item)) { + // and now add an alert + $add_alert = true; + // then set the 'before_time' value to self::REMINDER_STOP to permit future "after reminders" + $data['before_time'] = self::REMINDER_STOP; + $pm_taskrecall = new PluginProcessmakerTaskrecall(); + $pm_taskrecall->update($data); + } + if ($data['after_time'] >= 0) { + // if task "after reminder" is set, then compute new when for the first task "after reminder" + $new_when = strtotime($pm_task->fields['end']) + $data['after_time']; + } + } elseif ($data['after_time'] >= 0) { + // then task "after reminder" + if ($pm_task->sendNotification('task_overdue', $glpi_task, $glpi_item)) { + // and now add an alert + $add_alert = true; + // then compute the new when for the next task "after reminder" + $new_when = strtotime($data['when']) + $data['after_time']; - // $query = "SELECT $fields FROM glpi_plugin_processmaker_taskcategories $join ".$where." ".$orderby.";"; + // Add a follow-up in the hosting item to indicate the sending of the reminder + $fu = new ITILFollowup(); + $input = $fu->fields; - // return $DB->query($query); - //} + $fucontent = sprintf( + __("Case: '%s',
    Task: '%s',
    A reminder has been sent to:
    ", 'processmaker'), + $data['gppc-name'], + Dropdown::getDropdownName("glpi_taskcategories", $glpi_task->fields["taskcategories_id"]) + ); + + if (isset($glpi_task->fields['users_id_tech']) && $glpi_task->fields['users_id_tech'] > 0) { + // get infos for user + $dbu = new DbUtils; + $userinfos = $dbu->getUserName($glpi_task->fields['users_id_tech'], 2); + $fucontent .= "-> " . $userinfos['name'] . "
    "; + } + + if (isset($glpi_task->fields['groups_id_tech']) && $glpi_task->fields['groups_id_tech'] > 0) { + // get infos for group + $grp = new Group(); + $grp->getFromDB($glpi_task->fields['groups_id_tech']); + $fucontent .= "-> " . $grp->fields['name'] . "
    "; + } + + $input['content'] = $DB->escape($fucontent); + $input['is_private'] = 0; + //$input['requesttypes_id'] = ; + $input['items_id'] = $glpi_item->getID(); + $input['users_id'] = ($data['users_id'] > 0 ? $data['users_id'] : $pmconfig['users_id']); + $input['itemtype'] = $glpi_item->getType(); + + $fu->add($input); + } + } + + if ($new_when != 0) { + // if the new_when is less than glpi_currenttime, then set it to be greater than glpi_currenttime + // to prevent send of many "after reminders" in case of late cron that missed one or several "after reminders" + $glpi_currenttime = strtotime($_SESSION["glpi_currenttime"]); + if ($new_when < $glpi_currenttime + $data['after_time']) { + $new_when = $glpi_currenttime + $data['after_time']; + } + $data['when'] = date("Y-m-d H:i:s", $new_when); + $pm_taskrecall = new PluginProcessmakerTaskrecall(); + $pm_taskrecall->update($data); + } + + if ($add_alert) { + $cron_status = 1; + $crontask->addVolume(1); + $crontask->log(sprintf(__('Reminder for case #%s has been sent!', 'processmaker'), $data['gppt-cases_id'])); + + $pm_taskalert = new PluginProcessmakerTaskalert(); + $input["plugin_processmaker_taskrecalls_id"] = $data['id']; + $pm_taskalert->add($input); + } else { + // Clean item + $pr->delete($data); + } + } + return $cron_status; + } + static function getAllBeforeReminders() { + $possible_values = []; + $possible_values[self::REMINDER_NONE] = __('None'); + + $min_values = [0, 15, 30]; + foreach ($min_values as $val) { + $possible_values[$val * MINUTE_TIMESTAMP] = sprintf(_n('%d minute', '%d minutes', $val), $val); + } + + $h_values = [1, 2, 4, 8, 12]; + foreach ($h_values as $val) { + $possible_values[$val * HOUR_TIMESTAMP] = sprintf(_n('%d hour', '%d hours', $val), $val); + } + $d_values = [1, 2]; + foreach ($d_values as $val) { + $possible_values[$val * DAY_TIMESTAMP] = sprintf(_n('%d day', '%d days', $val), $val); + } + $w_values = [1]; + foreach ($w_values as $val) { + $possible_values[$val * WEEK_TIMESTAMP] = sprintf(_n('%d week', '%d weeks', $val), $val); + } + + return $possible_values; + } + + + static function getBeforeReminder($value) { + $arr = self::getAllBeforeReminders(); + if (array_key_exists($value, $arr)) { + return $arr[$value]; + } + return null; + } + + + static function getSpecificValueToDisplay($field, $values, array $options=[]) { + if (!is_array($values)) { + $values = [$field => $values]; + } + switch ($field) { + case 'before_time': + return self::getBeforeReminder($values[$field]); + case 'after_time': + return self::getAfterReminder($values[$field]); + } + return parent::getSpecificValueToDisplay($field, $values, $options); + } + + + static function getSpecificValueToSelect($field, $name='', $values='', array $options=[]) { + if (!is_array($values)) { + $values = [$field => $values]; + } + $options['display'] = false; + $options['name'] = $name; + $options['value'] = $values[$field]; + switch ($field) { + case 'before_time' : + return Dropdown::showFromArray($name, self::getAllBeforeReminders(), $options); + case 'after_time' : + return Dropdown::showFromArray($name, self::getAllAfterReminders(), $options); + } + + return parent::getSpecificValueToSelect($field, $name, $values, $options); + } } diff --git a/inc/taskrecall.class.php b/inc/taskrecall.class.php new file mode 100644 index 0000000..79875be --- /dev/null +++ b/inc/taskrecall.class.php @@ -0,0 +1,30 @@ +. +-------------------------------------------------------------------------- + */ +class PluginProcessmakerTaskrecall extends CommonDBTM { + +} diff --git a/inc/user.class.php b/inc/user.class.php index 8b2aa6e..5831d6e 100644 --- a/inc/user.class.php +++ b/inc/user.class.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/install.php b/install/install.php index 29adfb6..5f0a7cb 100644 --- a/install/install.php +++ b/install/install.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -34,23 +34,23 @@ function processmaker_install() { $config = Config::getConfigurationValues('plugin:processmaker'); $config += [ - 'pm_server_URL' => 'http://localhost/', - 'pm_workspace' => 'workflow', - 'pm_admin_user' => 'NULL', - 'pm_admin_passwd' => 'NULL', - 'pm_theme' => 'glpi_classic', - 'date_mod' => $_SESSION["glpi_currenttime"], - 'taskcategories_id' => 'NULL', - 'users_id' => 'NULL', - 'pm_group_guid' => 'NULL', - 'pm_dbserver_name' => 'NULL', - 'pm_dbname' => 'wf_workflow', - 'pm_dbserver_user' => 'NULL', - 'pm_dbserver_passwd' => 'NULL', - 'maintenance' => 0, - 'ssl_verify' => 0, - 'db_version' => '4.4.0', - 'max_cases_per_item' => 0, + 'pm_server_URL' => 'http://localhost/', + 'pm_workspace' => 'workflow', + 'pm_admin_user' => 'NULL', + 'pm_admin_passwd' => 'NULL', + 'pm_theme' => 'glpi_classic', + 'date_mod' => $_SESSION["glpi_currenttime"], + 'taskcategories_id' => 'NULL', + 'users_id' => 'NULL', + 'pm_group_guid' => 'NULL', + 'pm_dbserver_name' => 'NULL', + 'pm_dbname' => 'wf_workflow', + 'pm_dbserver_user' => 'NULL', + 'pm_dbserver_passwd' => 'NULL', + 'maintenance' => 0, + 'ssl_verify' => 0, + 'db_version' => '4.6.0', + 'max_cases_per_item' => 0, 'is_reassignreason_mandatory' => 0 ]; diff --git a/install/mysql/processmaker-empty.sql b/install/mysql/processmaker-empty.sql index 17cd7c4..22e3972 100644 --- a/install/mysql/processmaker-empty.sql +++ b/install/mysql/processmaker-empty.sql @@ -93,6 +93,7 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_processmaker_processes` ( `maintenance` TINYINT(1) NOT NULL DEFAULT '0', `max_cases_per_item` INT UNSIGNED NOT NULL DEFAULT '0', `is_reassignreason_mandatory` TINYINT(1) NOT NULL DEFAULT '-2', + `plugin_processmaker_processcategories_id` INT UNSIGNED NULL, PRIMARY KEY (`id`), UNIQUE KEY `process_guid` (`process_guid`) ) ENGINE=InnoDB; @@ -116,18 +117,46 @@ CREATE TABLE `glpi_plugin_processmaker_processes_profiles` ( -- Dumping structure for table glpi.glpi_plugin_processmaker_taskcategories CREATE TABLE `glpi_plugin_processmaker_taskcategories` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `plugin_processmaker_processes_id` INT UNSIGNED NOT NULL, + `pm_task_guid` VARCHAR(32) NOT NULL, + `taskcategories_id` INT UNSIGNED NOT NULL, + `is_start` TINYINT(1) NOT NULL DEFAULT '0', + `is_active` TINYINT(1) NOT NULL DEFAULT '1', + `is_subprocess` TINYINT(1) NOT NULL DEFAULT '0', + `is_reassignreason_mandatory` TINYINT(1) NOT NULL DEFAULT '-2', + `before_time` INT NOT NULL DEFAULT '-10', + `after_time` INT NOT NULL DEFAULT '-10', + `users_id` INT UNSIGNED NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `pm_task_guid` (`pm_task_guid`), + UNIQUE INDEX `taskcategories_id` (`taskcategories_id`), + INDEX `plugin_processmaker_processes_id` (`plugin_processmaker_processes_id`) +) ENGINE=InnoDB; + + +-- Dumping structure for table glpi.glpi_plugin_processmaker_taskrecalls +CREATE TABLE `glpi_plugin_processmaker_taskrecalls` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `plugin_processmaker_processes_id` INT UNSIGNED NOT NULL, - `pm_task_guid` VARCHAR(32) NOT NULL, - `taskcategories_id` INT UNSIGNED NOT NULL, - `is_start` TINYINT(1) NOT NULL DEFAULT '0', - `is_active` TINYINT(1) NOT NULL DEFAULT '1', - `is_subprocess` TINYINT(1) NOT NULL DEFAULT '0', - `is_reassignreason_mandatory` TINYINT(1) NOT NULL DEFAULT '-2', + `plugin_processmaker_tasks_id` INT UNSIGNED NOT NULL, + `before_time` INT NOT NULL DEFAULT '-10', + `after_time` INT NOT NULL DEFAULT '-10', + `when` TIMESTAMP NULL DEFAULT NULL, + `users_id` INT UNSIGNED NULL, PRIMARY KEY (`id`), - UNIQUE INDEX `pm_task_guid` (`pm_task_guid`), - UNIQUE INDEX `items` (`taskcategories_id`), - INDEX `plugin_processmaker_processes_id` (`plugin_processmaker_processes_id`) + UNIQUE INDEX `item` (`plugin_processmaker_tasks_id`), + INDEX `when` (`when`) +) ENGINE=InnoDB; + + +-- Dumping structure for table glpi.glpi_plugin_processmaker_taskalerts +CREATE TABLE `glpi_plugin_processmaker_taskalerts` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `plugin_processmaker_taskrecalls_id` INT UNSIGNED NOT NULL DEFAULT '0', + `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + INDEX `plugin_processmaker_taskrecalls_id` (`plugin_processmaker_taskrecalls_id`), + INDEX `date` (`date`) ) ENGINE=InnoDB; @@ -187,6 +216,14 @@ CREATE TABLE IF NOT EXISTS `glpi_plugin_processmaker_reassignreasontranslations` INDEX `plugin_processmaker_taskcategories_id` (`plugin_processmaker_taskcategories_id`) ) ENGINE=InnoDB; +-- Dumping structure for table glpi.glpi_plugin_processmaker_processcategories +CREATE TABLE `glpi_plugin_processmaker_processcategories` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(250) NOT NULL DEFAULT '', + `category_guid` VARCHAR(32) NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `category_guid` (`category_guid`) +) ENGINE=InnoDB; /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; diff --git a/install/update.php b/install/update.php index bed0146..17c0eef 100644 --- a/install/update.php +++ b/install/update.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -106,6 +106,15 @@ function processmaker_update() { include_once(PLUGIN_PROCESSMAKER_ROOT . "/install/update_4_0_2_to_4_4_0.php"); $new_version = update_4_0_2_to_4_4_0(); + case '4.4.0' : + // will upgrade 4.4.0 to 4.5.0 + include_once(PLUGIN_PROCESSMAKER_ROOT . "/install/update_4_4_0_to_4_5_0.php"); + $new_version = update_4_4_0_to_4_5_0(); + case '4.5.0' : + // will upgrade 4.5.0 to 4.6.0 + include_once(PLUGIN_PROCESSMAKER_ROOT . "/install/update_4_5_0_to_4_6_0.php"); + $new_version = update_4_5_0_to_4_6_0(); + } if (isset($new_version) && $new_version !== false) { diff --git a/install/update_3_2_8_to_3_2_9.php b/install/update_3_2_8_to_3_2_9.php index 4bfb9b8..7ab042f 100644 --- a/install/update_3_2_8_to_3_2_9.php +++ b/install/update_3_2_8_to_3_2_9.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_2_9_to_3_3_0.php b/install/update_3_2_9_to_3_3_0.php index bc2d93f..0560447 100644 --- a/install/update_3_2_9_to_3_3_0.php +++ b/install/update_3_2_9_to_3_3_0.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_3_0_to_3_3_1.php b/install/update_3_3_0_to_3_3_1.php index a6fca18..4997cf4 100644 --- a/install/update_3_3_0_to_3_3_1.php +++ b/install/update_3_3_0_to_3_3_1.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_3_1_to_3_3_8.php b/install/update_3_3_1_to_3_3_8.php index f298b21..2545d83 100644 --- a/install/update_3_3_1_to_3_3_8.php +++ b/install/update_3_3_1_to_3_3_8.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_3_8_to_3_4_9.php b/install/update_3_3_8_to_3_4_9.php index 5e3ed56..4ea4265 100644 --- a/install/update_3_3_8_to_3_4_9.php +++ b/install/update_3_3_8_to_3_4_9.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_4_10_to_4_0_0.php b/install/update_3_4_10_to_4_0_0.php index 6a6eb0f..cb84cb6 100644 --- a/install/update_3_4_10_to_4_0_0.php +++ b/install/update_3_4_10_to_4_0_0.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_3_4_9_to_3_4_10.php b/install/update_3_4_9_to_3_4_10.php index 6869ff6..35588ca 100644 --- a/install/update_3_4_9_to_3_4_10.php +++ b/install/update_3_4_9_to_3_4_10.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_4_0_0_to_4_0_1.php b/install/update_4_0_0_to_4_0_1.php index 8287d9f..d6df34e 100644 --- a/install/update_4_0_0_to_4_0_1.php +++ b/install/update_4_0_0_to_4_0_1.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -43,7 +43,7 @@ function update_4_0_0_to_4_0_1() { UNIQUE INDEX `guid_version` (`guid`, `version`), INDEX `plugin_processmaker_cases_id` (`plugin_processmaker_cases_id`), INDEX `is_output` (`is_output`) - ) ENGINE=InnoDB DEFAULT;"; + ) ENGINE=InnoDB;"; $DB->query($query) or die("error when creating glpi_plugin_processmaker_documents table" . $DB->error()); $query = "ALTER TABLE `glpi_plugin_processmaker_crontaskactions` diff --git a/install/update_4_0_1_to_4_0_2.php b/install/update_4_0_1_to_4_0_2.php index b1f39dd..3c19c4d 100644 --- a/install/update_4_0_1_to_4_0_2.php +++ b/install/update_4_0_1_to_4_0_2.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_4_0_2_to_4_4_0.php b/install/update_4_0_2_to_4_4_0.php index 18b5f76..2d50868 100644 --- a/install/update_4_0_2_to_4_4_0.php +++ b/install/update_4_0_2_to_4_4_0.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/install/update_4_4_0_to_4_5_0.php b/install/update_4_4_0_to_4_5_0.php new file mode 100644 index 0000000..852ae1d --- /dev/null +++ b/install/update_4_4_0_to_4_5_0.php @@ -0,0 +1,71 @@ +. +-------------------------------------------------------------------------- + */ +function update_4_4_0_to_4_5_0() { + global $DB; + + if (!$DB->tableExists('glpi_plugin_processmaker_taskrecalls')) { + $query = "CREATE TABLE `glpi_plugin_processmaker_taskrecalls` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `plugin_processmaker_tasks_id` INT UNSIGNED NOT NULL, + `before_time` INT NOT NULL DEFAULT '-10', + `after_time` INT NOT NULL DEFAULT '-10', + `when` TIMESTAMP NULL DEFAULT NULL, + `users_id` INT UNSIGNED NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `item` (`plugin_processmaker_tasks_id`), + INDEX `when` (`when`) + ) ENGINE=InnoDB;"; + $DB->query($query) or die("error when creating glpi_plugin_processmaker_taskrecalls table" . $DB->error()); + } + + if (!$DB->tableExists('glpi_plugin_processmaker_taskalerts')) { + $query = "CREATE TABLE `glpi_plugin_processmaker_taskalerts` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `plugin_processmaker_taskrecalls_id` INT UNSIGNED NOT NULL, + `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + INDEX `plugin_processmaker_taskrecalls_id` (`plugin_processmaker_taskrecalls_id`), + INDEX `date` (`date`) + ) ENGINE=InnoDB;"; + + $DB->query($query) or die("error when creating glpi_plugin_processmaker_taskalerts table" . $DB->error()); + } + + if (!$DB->fieldExists('glpi_plugin_processmaker_taskcategories', 'reminder_recall_time')) { + // add the field into table + $query = "ALTER TABLE `glpi_plugin_processmaker_taskcategories` + ADD COLUMN `before_time` INT NOT NULL DEFAULT '-10', + ADD COLUMN `after_time` INT NOT NULL DEFAULT '-10', + ADD COLUMN `users_id` INT UNSIGNED NULL + ;"; + + $DB->query($query) or die("error when adding reminder_recall_time field to glpi_plugin_processmaker_taskcategories table" . $DB->error()); + } + + return '4.5.0'; +} \ No newline at end of file diff --git a/install/update_4_5_0_to_4_6_0.php b/install/update_4_5_0_to_4_6_0.php new file mode 100644 index 0000000..6d7cfb4 --- /dev/null +++ b/install/update_4_5_0_to_4_6_0.php @@ -0,0 +1,50 @@ +. +-------------------------------------------------------------------------- + */ +function update_4_5_0_to_4_6_0() { + global $DB; + + if (!$DB->tableExists('glpi_plugin_processmaker_processcategories')) { + $query = "CREATE TABLE `glpi_plugin_processmaker_processcategories` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(250) NOT NULL DEFAULT '', + `category_guid` VARCHAR(32) NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `category_guid` (`category_guid`) + );"; + + $DB->query($query) or die("error when creating glpi_plugin_processmaker_processcategories table" . $DB->error()); + } + if (!$DB->fieldExists('glpi_plugin_processmaker_processes', 'plugin_processmaker_processcategories_id')) { + $query = "ALTER TABLE `glpi_plugin_processmaker_processes` + ADD COLUMN `plugin_processmaker_processcategories_id` INT UNSIGNED NULL AFTER `is_reassignreason_mandatory`; + "; + + $DB->query($query) or die("error when creating glpi_plugin_processmaker_processcategories table" . $DB->error()); + } + return '4.6.0'; +} \ No newline at end of file diff --git a/install/update_to_3_2_8.php b/install/update_to_3_2_8.php index 0b89e6f..9868be5 100644 --- a/install/update_to_3_2_8.php +++ b/install/update_to_3_2_8.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/js/cases.js b/js/cases.js index a653adf..6623d31 100644 --- a/js/cases.js +++ b/js/cases.js @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/js/central.js b/js/central.js index 04b92ee..19a57e1 100644 --- a/js/central.js +++ b/js/central.js @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/js/helpdesk.public.js.php b/js/helpdesk.public.js.php index 96a08cc..b62eaf5 100644 --- a/js/helpdesk.public.js.php +++ b/js/helpdesk.public.js.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/js/planning.js b/js/planning.js index 9c00f3e..0f4f671 100644 --- a/js/planning.js +++ b/js/planning.js @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/js/processmaker_icon.js b/js/processmaker_icon.js index 6f1c668..741a870 100644 --- a/js/processmaker_icon.js +++ b/js/processmaker_icon.js @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- diff --git a/processmaker.xml b/processmaker.xml index c6b4eb7..3bd15e8 100644 --- a/processmaker.xml +++ b/processmaker.xml @@ -41,11 +41,11 @@ 9.4 - 4.4.1 + 4.7.2 9.5 - 5.0.3 + 5.2.3 10.0 diff --git a/scripts/caseDump.php b/scripts/caseDump.php index bf1d5ec..12127a7 100644 --- a/scripts/caseDump.php +++ b/scripts/caseDump.php @@ -1,4 +1,31 @@ . +-------------------------------------------------------------------------- + */ + // to dump case records, to be able to restore case state // Ensure current directory when run from crontab diff --git a/scripts/caseRestore.php b/scripts/caseRestore.php index 1b076d3..ca775ba 100644 --- a/scripts/caseRestore.php +++ b/scripts/caseRestore.php @@ -1,4 +1,30 @@ . +-------------------------------------------------------------------------- + */ // to restore case state diff --git a/setup.php b/setup.php index b193489..efb3874 100644 --- a/setup.php +++ b/setup.php @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------------- ProcessMaker plugin for GLPI -Copyright (C) 2014-2023 by Raynet SAS a company of A.Raymond Network. +Copyright (C) 2014-2024 by Raynet SAS a company of A.Raymond Network. https://www.araymond.com/ ------------------------------------------------------------------------- @@ -25,7 +25,7 @@ You should have received a copy of the GNU General Public License along with this plugin. If not, see . -------------------------------------------------------------------------- */ -define('PROCESSMAKER_VERSION', '5.0.3'); +define('PROCESSMAKER_VERSION', '5.2.3'); // Minimal GLPI version, inclusive define('PLUGIN_PROCESSMAKER_MIN_GLPI', '10.0'); @@ -33,7 +33,7 @@ define('PLUGIN_PROCESSMAKER_MIN_GLPI', '10.0'); define('PLUGIN_PROCESSMAKER_MAX_GLPI', '10.1'); // Minimal PM version, inclusive -define('PLUGIN_PROCESSMAKER_MIN_PM', '3.3.0-community-RE-2.0'); +define('PLUGIN_PROCESSMAKER_MIN_PM', '3.3.0-community-RE-2.8'); // Maximum PM version, inclusive define('PLUGIN_PROCESSMAKER_MAX_PM', '3.3.0-community-RE-2.99'); @@ -63,6 +63,7 @@ function plugin_init_processmaker() { Plugin::registerClass('PluginProcessmakerTask', ['notificationtemplates_types' => true]); Plugin::registerClass('PluginProcessmakerTaskCategory', ['addtabon' => 'TaskCategory']); + Plugin::registerClass('PluginProcessmakerProcessCategory'); if (Session::haveRightsOr("config", [READ, UPDATE])) { Plugin::registerClass('PluginProcessmakerConfig', ['addtabon' => 'Config']); @@ -77,6 +78,8 @@ function plugin_init_processmaker() { $PLUGIN_HOOKS['pre_show_item']['processmaker'] = ['PluginProcessmakerProcessmaker', 'pre_show_item_processmaker']; + $PLUGIN_HOOKS['post_show_item']['processmaker'] + = ['PluginProcessmakerProcessmaker', 'post_show_item_processmaker']; $PLUGIN_HOOKS['pre_show_tab']['processmaker'] = ['PluginProcessmakerProcessmaker', 'pre_show_tab_processmaker'];