Commit 5a95daac authored by Cédric Anne's avatar Cédric Anne Committed by Johan Cwiklinski

ITIL timeline fixes

 - fix changelog,
 - fix knowbase items comments styles,
 - fix missing "itemtype" value for existing ticketfollowup elements,
 - fix detection of fields in migration,
 - fix bigdump generation,
 - use 'getFormURLWithID' instead of contatenating id with 'getFormURL'
 - factorize deletion of linked followups,
 - factorize 'canApprove',
 - factorize followups in notifications,
 - fixes some docblock,
 - remove dead code,
 - put back TicketFollowup to handle deprecation state
 - remove dead code
 - add ITILFollowup in API
 - Handle followups in notifications
parent 3b1e836f
......@@ -10,9 +10,6 @@ The present file will list all changes made to the project; according to the
- Ability to link project with problems and tickets.
- Add followups to Changes and Problems
- Add timeline to Changes and Problems
- Fix styles, search, and tests
- Ability to link project with problems and tickets
- TicketFollowup changed to ITILFollowup
- Search on devices from Printers and Network equipments
### Changed
......@@ -22,16 +19,21 @@ The present file will list all changes made to the project; according to the
#### Changes
- Plugins are now loaded in ajax files.
- `TicketFollowup` has been replaced by `ITILFollowup`
#### Deprecated
- Remove `$CFG_GLPI['use_rich_text']` parameter. Will now be `true` per default.
- Remove `$CFG_GLPI['ticket_timeline']` parameter. Will now be `true` per default.
- Remove `$CFG_GLPI['ticket_timeline_keep_replaced_tabs']` parameter. Will now be `false` per default.
- Move `TicketFollowup::showFormMassiveAction` to `ITILFollowup` and deprecate.
- Move `TicketFollowup::showMassiveActionsSubForm` to `ITILFollowup` and deprecate.
- Move `TicketFollowup::processMassiveActionsForOneItemtype` to `ITILFollowup` and deprecate.
- Move `TicketFollowup::showFormMassiveAction` to `ITILFollowup` and deprecate.
- Usage of `TicketFollowup` class has been deprecated.
The following methods have been deprecated:
- `Ticket::getTicketActors()`
- `Ticket::processMassiveActionsForOneItemtype()`
- `Ticket::showFormMassiveAction()`
- `Ticket::showMassiveActionsSubForm()`
#### Removed
......
......@@ -3329,7 +3329,8 @@ a.copyright {
border-right-color: transparent !important;
}
.timeline_history .ITILFollowup:after { border-color: #E0E0E0;}
.timeline_history .ITILFollowup:after,
.timeline_history .KnowbaseItemComment:after { border-color: #E0E0E0;}
.timeline_history .ITILTask:after { border-color: #FEDA90;}
.timeline_history .Solution:after { border-color: #9FD6ED;}
.timeline_history .ITILValidation.status_3:after { border-color: #A1D7A2;}
......@@ -3387,7 +3388,8 @@ a.copyright {
opacity: 1;
}
.timeline_history .h_content.ITILFollowup {
.timeline_history .h_content.ITILFollowup,
.timeline_history .h_content.KnowbaseItemComment {
background-color: #E0E0E0;
color: #535353;
background-image: url(../pics/timeline/followup.png);
......@@ -3518,7 +3520,8 @@ a.copyright {
position: absolute;
}
.timeline_history .h_content.ITILFollowup .read_more {
.timeline_history .h_content.ITILFollowup .read_more,
.timeline_history .h_content.KnowbaseItemComment .read_more {
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(241,244,227,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(241,244,227,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(241,244,227,1) 100%); /* Chrome10+,Safari5.1+ */
......
......@@ -71,7 +71,7 @@ if (isset($_POST["add"])) {
Event::log($fup->getField('items_id'), strtolower($_POST['itemtype']), 4, "tracking",
//TRANS: %s is the user login
sprintf(__('%s updates a followup'), $_SESSION["glpiname"]));
Html::redirect($track->getFormURL()."?id=".$fup->getField('items_id'));
Html::redirect($track->getFormURLWithID($fup->getField('items_id')));
} else if (isset($_POST["purge"])) {
$fup->check($_POST['id'], PURGE);
......@@ -80,7 +80,7 @@ if (isset($_POST["add"])) {
Event::log($fup->getField('items_id'), strtolower($_POST['itemtype']), 4, "tracking",
//TRANS: %s is the user login
sprintf(__('%s purges a followup'), $_SESSION["glpiname"]));
Html::redirect($track->getFormURL()."?id=".$fup->getField('items_id'));
Html::redirect($track->getFormURLWithID($fup->getField('items_id')));
}
Html::displayErrorAndDie('Lost');
......@@ -2287,6 +2287,7 @@ abstract class API extends CommonGLPI {
$hclasses[] = "Change_Ticket";
$hclasses[] = "Item_Ticket";
$hclasses[] = "ITILSolution";
$hclasses[] = "ITILFollowup";
break;
case 'Problem' :
......@@ -2296,6 +2297,7 @@ abstract class API extends CommonGLPI {
$hclasses[] = "Problem_Ticket";
$hclasses[] = "Item_Problem";
$hclasses[] = "ITILSolution";
$hclasses[] = "ITILFollowup";
break;
case 'Change' :
......@@ -2306,6 +2308,7 @@ abstract class API extends CommonGLPI {
$hclasses[] = "Change_Ticket";
$hclasses[] = "Change_Item";
$hclasses[] = "ITILSolution";
$hclasses[] = "ITILFollowup";
break;
case 'Project' :
......
......@@ -273,6 +273,11 @@ function glpi_autoload($classname) {
$dir = GLPI_ROOT . "/inc/";
// Deprecation warn for TicketFollowup
if ($classname === 'TicketFollowup') {
Toolbox::deprecated('TicketFollowup has been replaced by ITILFollowup.');
}
if ($plug = isPluginItemType($classname)) {
$plugname = strtolower($plug['plugin']);
$dir = GLPI_ROOT . "/plugins/$plugname/inc/";
......
......@@ -131,20 +131,6 @@ class Change extends CommonITILObject {
}
/**
* Is the current user have right to approve solution of the current change ?
*
* @return boolean
**/
function canApprove() {
return (($this->fields["users_id_recipient"] === Session::getLoginUserID())
|| $this->isUser(CommonITILActor::REQUESTER, Session::getLoginUserID())
|| (isset($_SESSION["glpigroups"])
&& $this->haveAGroup(CommonITILActor::REQUESTER, $_SESSION["glpigroups"])));
}
/**
* Is the current user have right to create the current change ?
*
......@@ -161,7 +147,9 @@ class Change extends CommonITILObject {
/**
* is the current user could reopen the current change
* @since 9.2
*
* @since 9.4.0
*
* @return boolean
*/
function canReopen() {
......@@ -279,13 +267,6 @@ class Change extends CommonITILObject {
function cleanDBonPurge() {
global $DB;
$DB->delete(
'glpi_itilfollowups', [
'items_id' => $this->fields['id'],
'itemtype' => 'Change'
]
);
$DB->delete(
'glpi_changetasks', [
'changes_id' => $this->fields['id']
......
......@@ -147,11 +147,29 @@ abstract class CommonITILObject extends CommonDBTM {
return false;
}
/**
* Is the current user have right to approve solution of the current ITIL object.
*
* @since 9.4.0
*
* @return boolean
*/
function canApprove() {
return (($this->fields["users_id_recipient"] === Session::getLoginUserID())
|| $this->isUser(CommonITILActor::REQUESTER, Session::getLoginUserID())
|| (isset($_SESSION["glpigroups"])
&& $this->haveAGroup(CommonITILActor::REQUESTER, $_SESSION["glpigroups"])));
}
/**
* Is the current user have right to add followups to the current ITIL Object ?
*
* @since 9.4.0
*
* @return boolean
**/
*/
function canAddFollowups() {
return Session::haveRight(static::$rightname, UPDATE) and Session::haveRight('followup', CREATE);
}
......@@ -191,10 +209,10 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Get the ITIL object closed, solved or waiting status list
*
* @since 0.90.1
* @since 9.4.0
*
* @return array
**/
*/
static function getReopenableStatusArray() {
return [self::CLOSED, self::SOLVED, self::WAITING];
}
......@@ -624,6 +642,9 @@ abstract class CommonITILObject extends CommonDBTM {
$itil_project = new Itil_Project();
$itil_project->cleanDBonItemDelete($this->getType(), $this->fields['id']);
$itilfollowup = new ITILFollowup();
$itilfollowup->cleanDBonItemDelete($this->getType(), $this->fields['id']);
}
......@@ -5662,7 +5683,8 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Summary of getTimelinePosition
* Returns the position of the $sub_type for the $user_id in the timeline
* @param int $items_id is the id of the ticket
*
* @param int $items_id is the id of the ITIL object
* @param string $sub_type is ITILFollowup, Document_Item, TicketTask, TicketValidation or Solution
* @param int $users_id
* @since 9.2
......@@ -5717,10 +5739,12 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Gets submit button with a status dropdown
*
* @since 9.4.0
*
* @param integer $items_id
* @param string $action (default 'add')
* @param string $action
*
* @return string HTML code for splitted submit button
**/
static function getSplittedSubmitButtonHtml($items_id, $action = "add") {
......@@ -5757,13 +5781,13 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Displays the timeline filter buttons
* @return void
*
* @since 9.4.0
**/
*
* @return void
*/
function filterTimeline() {
global $CFG_GLPI;
$pics_url = $CFG_GLPI['root_doc']."/pics/timeline";
echo "<div class='filter_timeline'>";
echo "<h3>".__("Timeline filter")." : </h3>";
echo "<ul>";
......@@ -5793,10 +5817,13 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Displays the timeline header (filters)
* @return void
*
* @since 9.4.0
**/
*
* @return void
*/
function showTimelineHeader() {
echo "<h2>".__("Actions historical")." : </h2>";
$this->filterTimeline();
}
......@@ -5805,11 +5832,15 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Displays the form at the top of the timeline.
* Includes buttons to add items to the timeline, new item form, and approbation form.
*
* @since 9.4.0
*
* @param integer $rand random value used by JavaScript function names
*
* @return void
* @since 9.4.0
**/
*/
function showTimelineForm($rand) {
global $CFG_GLPI;
$objType = self::getType();
......@@ -5820,8 +5851,6 @@ abstract class CommonITILObject extends CommonDBTM {
return false;
}
$supportsValidation = $objType === "Ticket" || $objType === "Change";
// javascript function for add and edit items
echo "<script type='text/javascript' >\n";
echo "function viewAddSubitem" . $this->fields['id'] . "$rand(itemtype) {\n";
......@@ -5880,8 +5909,6 @@ abstract class CommonITILObject extends CommonDBTM {
'$foreignKey': ".$this->fields['id'].",
'id' : items_id
});
};";
if (isset($_GET['load_kb_sol'])) {
......@@ -5956,12 +5983,12 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Retrieves all timeline items for this ITILObject
* @return mixed[] Timeline items
*
* @since 9.4.0
*
**/
* @return mixed[] Timeline items
*/
function getTimelineItems() {
global $DB, $CFG_GLPI;
$objType = self::getType();
$foreignKey = self::getForeignKeyField();
......@@ -5969,8 +5996,7 @@ abstract class CommonITILObject extends CommonDBTM {
$timeline = [];
$user = new User();
$group = new Group();
$user = new User();
$fupClass = 'ITILFollowup';
$followup_obj = new $fupClass;
......@@ -5983,10 +6009,6 @@ abstract class CommonITILObject extends CommonDBTM {
}
//checks rights
$showpublic = Session::haveRightsOr("followup", [ITILFollowup::SEEPUBLIC,
ITILFollowup::SEEPRIVATE])
|| Session::haveRightsOr("task", [CommonITILTask::SEEPUBLIC,
CommonITILTask::SEEPRIVATE]);
$restrict_fup = $restrict_task = "";
if (!Session::haveRight("followup", ITILFollowup::SEEPRIVATE)) {
$restrict_fup = " AND (`is_private` = 0
......@@ -6001,10 +6023,6 @@ abstract class CommonITILObject extends CommonDBTM {
OR `users_id` ='" . Session::getLoginUserID() . "') ";
}
if (!$showpublic) {
$restrict = " AND 1 = 0";
}
//add followups to timeline
if ($followup_obj->canview()) {
$followups = $followup_obj->find("items_id = ".$this->getID()." $restrict_fup", 'date DESC');
......@@ -6124,12 +6142,15 @@ abstract class CommonITILObject extends CommonDBTM {
/**
* Displays the timeline of items for this ITILObject
*
* @since 9.4.0
*
* @param integer $rand random value used by div
*
* @return void
* @since 9.4.0
**/
*/
function showTimeline($rand) {
global $CFG_GLPI, $DB, $autolink_options;
global $CFG_GLPI, $autolink_options;
$user = new User();
$group = new Group();
......@@ -6531,8 +6552,9 @@ abstract class CommonITILObject extends CommonDBTM {
* @param CommonDBTM $item The item whose form should be shown
* @param integer $id ID of the item
* @param mixed[] $params Array of extra parameters
*
* @return void
**/
*/
static function showSubForm(CommonDBTM $item, $id, $params) {
if ($item instanceof Document_Item) {
......@@ -6552,8 +6574,7 @@ abstract class CommonITILObject extends CommonDBTM {
* @since 9.4.0
*
* @return array[] of array[] of users and roles
*
**/
*/
public function getITILActors() {
global $DB;
......
......@@ -1519,7 +1519,7 @@ abstract class CommonITILTask extends CommonDBTM {
echo "<tr class='tab_bg_1'>";
echo "<td>".__('By')."</td>";
echo "<td colspan='2'>";
echo "<i class='fas fa-user'></i>$nbsp;";
echo "<i class='fas fa-user'></i>&nbsp;";
echo _n('User', 'Users', 1);
$params = ['name' => "users_id_tech",
'value' => (($ID > -1)
......
......@@ -780,7 +780,7 @@ class Document extends CommonDBTM {
'glpi_tickets.id' => $tickets_id,
'OR' => [
'glpi_tickets.content' => ['REGEXP', $regexPattern],
'glpi_itilfollowups.content' => ['REGEXP', $regexPattern],
'glpi_itilfollowups.content' => ['REGEXP', $regexPattern],
'glpi_tickettasks.content' => ['REGEXP', $regexPattern],
'glpi_itilsolutions.content' => ['REGEXP', $regexPattern]
]
......
This diff is collapsed.
......@@ -298,7 +298,7 @@ class KnowbaseItem_Comment extends CommonDBTM {
$html .= "</div>"; // h_user
$html .= "</div>"; //h_info
$html .= "<div class='h_content TicketFollowup'>";
$html .= "<div class='h_content KnowbaseItemComment'>";
$html .= "<div class='displayed_content'>";
if ($cancomment) {
......
......@@ -1114,6 +1114,12 @@ class NotificationTarget extends CommonDBChild {
}
/**
* Get SQL join to restrict by profile and by config to avoid send notification
* to a user without rights.
*
* @return string
*/
public function getProfileJoinSql() {
return " INNER JOIN `glpi_profiles_users`
......
......@@ -54,9 +54,6 @@ class NotificationTargetChange extends NotificationTargetCommonITILObject {
'solved' => __('Change solved'),
'validation' => __('Validation request'),
'validation_answer' => __('Validation request answer'),
'add_task' => __('New task'),
'update_task' => __('Update of a task'),
'delete_task' => __('Deletion of a task'),
'closed' => __('Closure of a change'),
'delete' => __('Deleting a change')];
......@@ -197,32 +194,6 @@ class NotificationTargetChange extends NotificationTargetCommonITILObject {
$data['##change.numberofitems##'] = count($data['items']);
//Get followups
$followup_restrict = [];
$followup_restrict['items_id'] = $item->getField('id');
if (!isset($options['additionnaloption']['show_private'])
|| !$options['additionnaloption']['show_private']) {
$followup_restrict['is_private'] = 0;
}
$followup_restrict['itemtype'] = 'Change';
//Followup infos
$followups = getAllDatasFromTable('glpi_itilfollowups', $followup_restrict, false, ['date_mod DESC', 'id ASC']);
$data['followups'] = [];
foreach ($followups as $followup) {
$tmp = [];
$tmp['##followup.isprivate##'] = Dropdown::getYesNo($followup['is_private']);
$tmp['##followup.author##'] = Html::clean(getUserName($followup['users_id']));
$tmp['##followup.requesttype##'] = Dropdown::getDropdownName('glpi_requesttypes',
$followup['requesttypes_id']);
$tmp['##followup.date##'] = Html::convDateTime($followup['date']);
$tmp['##followup.description##'] = $followup['content'];
$data['followups'][] = $tmp;
}
$data['##change.numberoffollowups##'] = count($data['followups']);
//Validation infos
if (isset($options['validation_id']) && $options['validation_id']) {
$restrict['glpi_changevalidations.id'] = $options['validation_id'];
......
......@@ -36,6 +36,8 @@ if (!defined('GLPI_ROOT')) {
abstract class NotificationTargetCommonITILObject extends NotificationTarget {
public $private_profiles = [];
public $html_tags = [
'##change.solution.description##',
'##followup.description##',
......@@ -56,7 +58,32 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
parent::__construct($entity, $event, $object, $options);
$this->options['sendprivate'] = false;
if (isset($options['followup_id'])) {
$this->options['sendprivate'] = $options['is_private'];
}
if (isset($options['task_id'])) {
$this->options['sendprivate'] = $options['is_private'];
}
}
function validateSendTo($event, array $infos, $notify_me = false) {
// Check global ones for notification to myself
if (!parent::validateSendTo($event, $infos, $notify_me)) {
return false;
}
// Private object and no right to see private items : do not send
if ($this->isPrivate()
&& (!isset($infos['additionnaloption']['show_private'])
|| !$infos['additionnaloption']['show_private'])) {
return false;
}
return true;
}
/**
......@@ -86,13 +113,21 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
**/
function getEvents() {
$events = ['requester_user' => __('New user in requesters'),
'requester_group' => __('New group in requesters'),
'observer_user' => __('New user in observers'),
'observer_group' => __('New group in observers'),
'assign_user' => __('New user in assignees'),
'assign_group' => __('New group in assignees'),
'assign_supplier' => __('New supplier in assignees')];
$events = [
'requester_user' => __('New user in requesters'),
'requester_group' => __('New group in requesters'),
'observer_user' => __('New user in observers'),
'observer_group' => __('New group in observers'),
'assign_user' => __('New user in assignees'),
'assign_group' => __('New group in assignees'),
'assign_supplier' => __('New supplier in assignees'),
'add_task' => __('New task'),
'update_task' => __('Update of a task'),
'delete_task' => __('Deletion of a task'),
'add_followup' => __("New followup"),
'update_followup' => __('Update of a followup'),
'delete_followup' => __('Deletion of a followup'),
];
asort($events);
return $events;
......@@ -525,6 +560,78 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
}
function addAdditionnalInfosForTarget() {
global $DB;
$iterator = $DB->request([
'SELECT' => ['profiles_id'],
'FROM' => 'glpi_profilerights',
'WHERE' => [
'name' => 'followup',
'rights' => ['&', ITILFollowup::SEEPRIVATE]
]
]);
while ($data = $iterator->next()) {
$this->private_profiles[$data['profiles_id']] = $data['profiles_id'];
}
}
function addAdditionnalUserInfo(array $data) {
global $DB;
if (!isset($data['users_id'])) {
return ['show_private' => 0];
}
$result = $DB->request([
'COUNT' => 'cpt',
'FROM' => 'glpi_profiles_users',
'WHERE' => [
'users_id' => $data['users_id'],
'profiles_id' => $this->private_profiles
] + getEntitiesRestrictCriteria('glpi_profiles_users', 'entities_id', $this->getEntity(), true)
])->next();
if ($result['cpt']) {
return ['show_private' => 1];
}
return ['show_private' => 0];
}
public function getProfileJoinSql() {
$query = " INNER JOIN `glpi_profiles_users`
ON (`glpi_profiles_users`.`users_id` = `glpi_users`.`id` ".
getEntitiesRestrictRequest("AND", "glpi_profiles_users", "entities_id",
$this->getEntity(), true).")";
if ($this->isPrivate()) {
$query .= " INNER JOIN `glpi_profiles`
ON (`glpi_profiles`.`id` = `glpi_profiles_users`.`profiles_id`
AND `glpi_profiles`.`interface` = 'central')
INNER JOIN `glpi_profilerights`
ON (`glpi_profiles`.`id` = `glpi_profilerights`.`profiles_id`
AND `glpi_profilerights`.`name` = 'followup'
AND `glpi_profilerights`.`rights` & ".
ITILFollowup::SEEPRIVATE.") ";
}
return $query;
}
function isPrivate() {
if (isset($this->options['sendprivate']) && ($this->options['sendprivate'] == 1)) {
return true;
}
return false;
}
/**
* Add additionnals targets for ITIL objects
*
......@@ -1022,6 +1129,31 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
// Complex mode
if (!$simple) {
$followup_restrict = [];
$followup_restrict['items_id'] = $item->getField('id');
if (!isset($options['additionnaloption']['show_private'])
|| !$options['additionnaloption']['show_private']) {
$followup_restrict['is_private'] = 0;
}
$followup_restrict['itemtype'] = $objettype;
//Followup infos
$followups = getAllDatasFromTable('glpi_itilfollowups', $followup_restrict, false, ['date_mod DESC', 'id ASC']);
$data['followups'] = [];
foreach ($followups as $followup) {
$tmp = [];
$tmp['##followup.isprivate##'] = Dropdown::getYesNo($followup['is_private']);
$tmp['##followup.author##'] = Html::clean(getUserName($followup['users_id']));
$tmp['##followup.requesttype##'] = Dropdown::getDropdownName('glpi_requesttypes',
$followup['requesttypes_id']);
$tmp['##followup.date##'] = Html::convDateTime($followup['date']);
$tmp['##followup.description##'] = $followup['content'];
$data['followups'][] = $tmp;
}
$data["##$objettype.numberoffollowups##"] = count($data['followups']);
$data['log'] = [];
// Use list_limit_max or load the full history ?
foreach (Log::getHistoryData($item, 0, $CFG_GLPI['list_limit_max']) as $log) {
......@@ -1248,6 +1380,12 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
$objettype.'.solution.description' => _n('Solution', 'Solutions', 1),
$objettype.'.observerusers' => _n('Watcher', 'Watchers', Session::getPluralNumber()),
$objettype.'.action' => _n('Event', 'Events', 1),
'followup.date' => __('Opening date'),
'followup.isprivate' => __('Private'),
'followup.author' => __('Writer'),
'followup.description' => __('Description'),
'followup.requesttype' => __('Request source'),
$objettype.'.numberoffollowups' => _x('quantity', 'Number of followups'),
$objettype.'.numberofunresolved' => __('Number of unresolved items'),
$objettype.'.numberofdocuments' => _x('quantity', 'Number of documents'),
$objettype.'.costtime' => __('Time cost'),
......@@ -1318,6 +1456,7 @@ abstract class NotificationTargetCommonITILObject extends NotificationTarget {
//Foreach global tags
$tags = ['log' => __('Historical'),
'followups' => _n('Followup', 'Followups', Session::getPluralNumber()),
'tasks' => _n('Task', 'Tasks', Session::getPluralNumber()),
'costs' => _n('Cost', 'Costs', Session::getPluralNumber()),
'authors' => _n('Requester', 'Requesters', Session::getPluralNumber()),
......
......@@ -50,9 +50,6 @@ class NotificationTargetProblem extends NotificationTargetCommonITILObject {
$events = ['new' => __('New problem'),
'update' => __('Update of a problem'),
'solved' => __('Problem solved'),
'add_task' => __('New task'),
'update_task' => __('Update of a task'),
'delete_task' => __('Deletion of a task'),
'closed' => __('Closure of a problem'),
'delete' => __('Deleting a problem')];
......@@ -185,32 +182,6 @@ class NotificationTargetProblem extends NotificationTargetCommonITILObject {
}
$data['##problem.numberofitems##'] = count($data['items']);
//Get followups
$followup_restrict = [];
$followup_restrict['items_id'] = $item->getField('id');
if (!isset($options['additionnaloption']['show_private'])
|| !$options['additionnaloption']['show_private']) {
$followup_restrict['is_private'] = 0;
}
$followup_restrict['itemtype'] = 'Problem';
//Followup infos
$followups = getAllDatasFromTable('glpi_itilfollowups', $followup_restrict, false, ['date_mod DESC', 'id ASC']);
$data['followups'] = [];
foreach ($followups as $followup) {
$tmp = [];
$tmp['##followup.isprivate##'] = Dropdown::getYesNo($followup['is_private']);
$tmp['##followup.author##'] = Html::clean(getUserName($followup['users_id']));
$tmp['##followup.requesttype##'] = Dropdown::getDropdownName('glpi_requesttypes',
$followup['requesttypes_id']);
$tmp['##followup.date##'] = Html::convDateTime($followup['date']);
$tmp['##followup.description##'] = $followup['content'];
$data['followups'][] = $tmp;
}
$data['##problem.numberoffollowups##'] = count($data['followups']);
}
return $data;