diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index e27a7a5e0c7..d390fd6f351 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2932,6 +2932,42 @@ class Ticket extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Return clicable link of object (with eventually picto) + * + * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) + * @return string HTML Code for Kanban thumb. + */ + public function getKanbanView($option = '') + { + global $langs, $selected,$arrayofselected,$obj; + $return = '
'; + $return .= '
'; + $return .= ''; + $return .= img_picto('', $this->picto); + $return .= ''; + $return .= '
'; + $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + if (in_array($this->id, $arrayofselected)) { + $selected = 1; + } + $return .= ''; + if (property_exists($this, 'fk_user_assign') && !empty($this->fk_user_assign)) { + $return .= '
'.$langs->trans("AssignedTo").' : '.$this->fk_user_assign.''; + } + if (property_exists($this, 'type_code') && !empty($this->type_code)) { + $return .= '
'.$langs->trans("Type").' : '; + $return .= $langs->getLabelFromKey($this->db, 'TicketTypeShort'.$this->type_code, 'c_ticket_type', 'code', 'label', $this->type_code); + } + if (method_exists($this, 'getLibStatut')) { + $return .= '
'.$this->getLibStatut(5).'
'; + } + $return .= '
'; + $return .= '
'; + $return .= '
'; + return $return; + } } diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 79db9e0e73e..1d2cefaf622 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -629,6 +629,9 @@ if ($projectid > 0 || $project_ref) { $arrayofselected = is_array($toselect) ? $toselect : array(); $param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } @@ -740,7 +743,10 @@ $url = DOL_URL_ROOT.'/ticket/card.php?action=create'.($socid ? '&socid='.$socid if (!empty($socid)) { $url .= '&socid='.$socid; } -$newcardbutton = dolGetButtonTitle($langs->trans('NewTicket'), '', 'fa fa-plus-circle', $url, '', $user->rights->ticket->write); +$newcardbutton = ''; +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('NewTicket'), '', 'fa fa-plus-circle', $url, '', $user->rights->ticket->write); $picto = 'ticket'; if ($socid > 0) { @@ -999,176 +1005,199 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $object->setVarsFromFetchObj($obj); $object->status = $object->fk_statut; // fk_statut is deprecated - // Show here line of result - print ''; - // Action column - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; - } - print ''; + if ($mode == 'kanban') { + if ($i == 0) { + print ''; + print '
'; } - print ''; - } - foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); - if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } - if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } - if (in_array($key, array('ref', 'fk_project'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; - } - if ($key == 'fk_statut' || $key == 'severity_code') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } - if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; - if ($key == 'fk_statut') { - print $object->getLibStatut(5); - } elseif ($key == 'subject') { - $s = $obj->subject; - print ''; - print dol_escape_htmltag($s); - print ''; - } elseif ($key == 'type_code') { - $s = $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); - print ''; - print $s; - print ''; - } elseif ($key == 'category_code') { - $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); - print ''; - print $s; - print ''; - } elseif ($key == 'severity_code') { - $s = $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code); - print ''; - print $s; - print ''; - } elseif ($key == 'tms') { - print dol_print_date($db->jdate($obj->$key), 'dayhour', 'tzuser'); - } elseif ($key == 'fk_user_create') { - if ($object->fk_user_create > 0) { - if (isset($conf->cache['user'][$object->fk_user_create])) { - $user_temp = $conf->cache['user'][$object->fk_user_create]; - } else { - $user_temp = new User($db); - $user_temp->fetch($object->fk_user_create); - $conf->cache['user'][$object->fk_user_create] = $user_temp; - } - print $user_temp->getNomUrl(-1); + print $object->getKanbanView(''); + } + if ($i == (min($num, $limit) - 1)) { + print '
'; + print ''; + } + } else { + // Show here line of result + print ''; + // Action column + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->rowid, $arrayofselected)) { + $selected = 1; } - } elseif ($key == 'fk_user_assign') { - if ($object->fk_user_assign > 0) { - if (isset($conf->cache['user'][$object->fk_user_assign])) { - $user_temp = $conf->cache['user'][$object->fk_user_assign]; - } else { - $user_temp = new User($db); - $user_temp->fetch($object->fk_user_assign); - $conf->cache['user'][$object->fk_user_assign] = $user_temp; - } - print $user_temp->getNomUrl(-1); + print ''; + } + print ''; + } + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } + if (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } + if (in_array($key, array('ref', 'fk_project'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; + } + if ($key == 'fk_statut' || $key == 'severity_code') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } + if (!empty($arrayfields['t.'.$key]['checked'])) { + print 'trans('Late') . ' : ' . $langs->trans('TicketsDelayForFirstResponseTooLong', $conf->global->TICKET_DELAY_BEFORE_FIRST_RESPONSE), 'warning', 'style="color: red;"', false, 0, 0, '', ''); + print $cssforfield; + if ($cssforfield && array_key_exists('css', $val) && $val['css']) { + print ' '; + } + if (array_key_exists('css', $val)) { + print $val['css']; + } + if ($cssforfield || (array_key_exists('css', $val) && $val['css'])) { + print '"'; + } + print '>'; + if ($key == 'fk_statut') { + print $object->getLibStatut(5); + } elseif ($key == 'subject') { + $s = $obj->subject; + print ''; + print dol_escape_htmltag($s); + print ''; + } elseif ($key == 'type_code') { + $s = $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); + print ''; + print $s; + print ''; + } elseif ($key == 'category_code') { + $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); + print ''; + print $s; + print ''; + } elseif ($key == 'severity_code') { + $s = $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code); + print ''; + print $s; + print ''; + } elseif ($key == 'tms') { + print dol_print_date($db->jdate($obj->$key), 'dayhour', 'tzuser'); + } elseif ($key == 'fk_user_create') { + if ($object->fk_user_create > 0) { + if (isset($conf->cache['user'][$object->fk_user_create])) { + $user_temp = $conf->cache['user'][$object->fk_user_create]; + } else { + $user_temp = new User($db); + $user_temp->fetch($object->fk_user_create); + $conf->cache['user'][$object->fk_user_create] = $user_temp; } - } elseif (!empty($conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE) && $hour_diff > $conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE) { - print " " . img_picto($langs->trans('Late') . ' : ' . $langs->trans('TicketsDelayFromLastResponseTooLong', $conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE), 'warning'); + print $user_temp->getNomUrl(-1); } - } - } else { // Example: key=fk_soc, obj->key=123 val=array('type'=>'integer', ... - $tmp = explode(':', $val['type']); - if ($tmp[0] == 'integer' && !empty($tmp[1]) && class_exists($tmp[1])) { - // It is a type of an foreign field. We will try to reduce the number of fetch that the showOutputField is making. - //var_dump('eeee-'.$key.'-'.$obj->$key.'-'.$val['type']); - if ($key && $obj->$key && $val['type'] && array_key_exists($key.'-'.$obj->$key.'-'.$val['type'], $cacheofoutputfield)) { - $result = $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']]; + } elseif ($key == 'fk_user_assign') { + if ($object->fk_user_assign > 0) { + if (isset($conf->cache['user'][$object->fk_user_assign])) { + $user_temp = $conf->cache['user'][$object->fk_user_assign]; + } else { + $user_temp = new User($db); + $user_temp->fetch($object->fk_user_assign); + $conf->cache['user'][$object->fk_user_assign] = $user_temp; + } + print $user_temp->getNomUrl(-1); + } + } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + print $object->showOutputField($val, $key, $db->jdate($obj->$key), ''); + } elseif ($key == 'ref') { + print $object->showOutputField($val, $key, $obj->$key, ''); + + // display a warning on untreated tickets + $is_open = ($object->status != Ticket::STATUS_CLOSED && $object->status != Ticket::STATUS_CANCELED ); + $should_show_warning = (!empty($conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE) || !empty($conf->global->TICKET_DELAY_BEFORE_FIRST_RESPONSE)); + if ($is_open && $should_show_warning) { + $date_last_msg_sent = (int) $object->date_last_msg_sent; + $hour_diff = ($now - $date_last_msg_sent) / 3600 ; + + if (!empty($conf->global->TICKET_DELAY_BEFORE_FIRST_RESPONSE && $date_last_msg_sent == 0)) { + $creation_date = $object->datec; + $hour_diff_creation = ($now - $creation_date) / 3600 ; + if ($hour_diff_creation > $conf->global->TICKET_DELAY_BEFORE_FIRST_RESPONSE) { + print " " . img_picto($langs->trans('Late') . ' : ' . $langs->trans('TicketsDelayForFirstResponseTooLong', $conf->global->TICKET_DELAY_BEFORE_FIRST_RESPONSE), 'warning', 'style="color: red;"', false, 0, 0, '', ''); + } + } elseif (!empty($conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE) && $hour_diff > $conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE) { + print " " . img_picto($langs->trans('Late') . ' : ' . $langs->trans('TicketsDelayFromLastResponseTooLong', $conf->global->TICKET_DELAY_SINCE_LAST_RESPONSE), 'warning'); + } + } + } else { // Example: key=fk_soc, obj->key=123 val=array('type'=>'integer', ... + $tmp = explode(':', $val['type']); + if ($tmp[0] == 'integer' && !empty($tmp[1]) && class_exists($tmp[1])) { + // It is a type of an foreign field. We will try to reduce the number of fetch that the showOutputField is making. + //var_dump('eeee-'.$key.'-'.$obj->$key.'-'.$val['type']); + if ($key && $obj->$key && $val['type'] && array_key_exists($key.'-'.$obj->$key.'-'.$val['type'], $cacheofoutputfield)) { + $result = $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']]; + } else { + $result = $object->showOutputField($val, $key, $obj->$key, ''); + $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']] = $result; + } } else { $result = $object->showOutputField($val, $key, $obj->$key, ''); - $cacheofoutputfield[$key.'-'.$obj->$key.'-'.$val['type']] = $result; } - } else { - $result = $object->showOutputField($val, $key, $obj->$key, ''); + print $result; } - print $result; - } - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + print ''; if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + $totalarray['nbfield']++; } - if (!isset($totalarray['val'])) { - $totalarray['val'] = array(); + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = array(); + } + if (!isset($totalarray['val']['t.'.$key])) { + $totalarray['val']['t.'.$key] = 0; + } + $totalarray['val']['t.'.$key] += $object->$key; } - if (!isset($totalarray['val']['t.'.$key])) { - $totalarray['val']['t.'.$key] = 0; - } - $totalarray['val']['t.'.$key] += $object->$key; } } - } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Action column - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->rowid, $arrayofselected)) { + $selected = 1; + } + print ''; } - print ''; + print ''; + } + if (!$i) { + $totalarray['nbfield']++; } - print ''; - } - if (!$i) { - $totalarray['nbfield']++; - } - print ''."\n"; + print ''."\n"; + } $i++; }