From 907669bb51d28f0c7cf8786343f631f665cee60f Mon Sep 17 00:00:00 2001 From: ATM john Date: Wed, 11 Sep 2019 23:30:09 +0200 Subject: [PATCH 01/32] New ticket messaging page --- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/lib/ticket.lib.php | 546 ++++++++++++++++++++++++++ htdocs/theme/eldy/global.inc.php | 1 + htdocs/theme/eldy/timeline.inc.php | 142 +++++++ htdocs/ticket/messaging.php | 238 +++++++++++ 5 files changed, 928 insertions(+), 1 deletion(-) create mode 100644 htdocs/theme/eldy/timeline.inc.php create mode 100644 htdocs/ticket/messaging.php diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c470231e5de..b1b4d3f57f4 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7428,7 +7428,7 @@ class Form */ public function showFilterAndCheckAddButtons($addcheckuncheckall = 0, $cssclass = 'checkforaction', $calljsfunction = 0) { - $out.=$this->showFilterButtons(); + $out=$this->showFilterButtons(); if ($addcheckuncheckall) { $out.=$this->showCheckAddButtons($cssclass, $calljsfunction); diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index c1d42bf25b7..35e94f29ca5 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -118,6 +118,11 @@ function ticket_prepare_head($object) $head[$h][2] = 'tabTicketLogs'; $h++; + // History + $head[$h][0] = DOL_URL_ROOT.'/ticket/messaging.php?track_id=' . $object->track_id; + $head[$h][1] = $langs->trans('Messaging'); + $head[$h][2] = 'tabTicketMessaging'; + $h++; complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticket', 'remove'); @@ -187,3 +192,544 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ print '
'; } + + + +/** + * Show html area with actions for ticket messaging. + * Note: Global parameter $param must be defined. + * + * @param Conf $conf Object conf + * @param Translate $langs Object langs + * @param DoliDB $db Object db + * @param mixed $filterobj Filter on object Adherent|Societe|Project|Product|CommandeFournisseur|Dolresource|Ticket|... to list events linked to an object + * @param Contact $objcon Filter on object contact to filter events on a contact + * @param int $noprint Return string but does not output it + * @param string $actioncode Filter on actioncode + * @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all). + * @param array $filters Filter on other fields + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @return string|void Return html part or void if noprint is 1 + */ +function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $noprint = 0, $actioncode = '', $donetodo = 'done', $filters = array(), $sortfield = 'a.datep,a.id', $sortorder = 'DESC') +{ + global $user, $conf; + global $form; + + global $param, $massactionbutton; + + dol_include_once('/comm/action/class/actioncomm.class.php'); + + // Check parameters + if (! is_object($filterobj) && ! is_object($objcon)) dol_print_error('', 'BadParameter'); + + $out=''; + $histo=array(); + $numaction = 0 ; + $now=dol_now('tzuser'); + + // Open DSI -- Fix order by -- Begin + $sortfield_list = explode(',', $sortfield); + $sortfield_label_list = array('a.id' => 'id', 'a.datep' => 'dp', 'a.percent' => 'percent'); + $sortfield_new_list = array(); + foreach ($sortfield_list as $sortfield_value) { + $sortfield_new_list[] = $sortfield_label_list[trim($sortfield_value)]; + } + $sortfield_new = implode(',', $sortfield_new_list); + + if (! empty($conf->agenda->enabled)) + { + // Recherche histo sur actioncomm + if (is_object($objcon) && $objcon->id > 0) { + $sql = "SELECT DISTINCT a.id, a.label as label,"; + } + else + { + $sql = "SELECT a.id, a.label as label,"; + } + $sql.= " a.datep as dp,"; + $sql.= " a.note as message,"; + $sql.= " a.datep2 as dp2,"; + $sql.= " a.percent as percent, 'action' as type,"; + $sql.= " a.fk_element, a.elementtype,"; + $sql.= " a.fk_contact,"; + $sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,"; + $sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; + if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; + elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", o.ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql.= ", o.ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') $sql.= ", o.ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') $sql.= ", o.ref"; + $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_action"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id"; + + $force_filter_contact = false; + if (is_object($objcon) && $objcon->id > 0) { + $force_filter_contact = true; + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as r ON a.id = r.fk_actioncomm"; + $sql.= " AND r.element_type = '" . $db->escape($objcon->table_element) . "' AND r.fk_element = " . $objcon->id; + } + + if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Dolresource') { + $sql.= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as er"; + $sql.= " ON er.resource_type = 'dolresource'"; + $sql.= " AND er.element_id = a.id"; + $sql.= " AND er.resource_id = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m"; + elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", ".MAIN_DB_PREFIX."product as o"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql.= ", ".MAIN_DB_PREFIX."ticket as o"; + elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') $sql.= ", ".MAIN_DB_PREFIX."bom_bom as o"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') $sql.= ", ".MAIN_DB_PREFIX."contrat as o"; + + $sql.= " WHERE a.entity IN (".getEntity('agenda').")"; + if ($force_filter_contact === false) { + if (is_object($filterobj) && in_array(get_class($filterobj), array('Societe', 'Client', 'Fournisseur')) && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id; + elseif (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id; + elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') + { + $sql.= " AND a.fk_element = m.rowid AND a.elementtype = 'member'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'Product') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'ticket'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'bom'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'contract'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + } + + // Condition on actioncode + if (! empty($actioncode)) + { + if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) + { + if ($actioncode == 'AC_NON_AUTO') $sql.= " AND c.type != 'systemauto'"; + elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND c.type = 'systemauto'"; + else + { + if ($actioncode == 'AC_OTH') $sql.= " AND c.type != 'systemauto'"; + elseif ($actioncode == 'AC_OTH_AUTO') $sql.= " AND c.type = 'systemauto'"; + } + } + else + { + if ($actioncode == 'AC_NON_AUTO') $sql.= " AND c.type != 'systemauto'"; + elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND c.type = 'systemauto'"; + else $sql.= " AND c.code = '".$db->escape($actioncode)."'"; + } + } + if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))"; + elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))"; + if (is_array($filters) && $filters['search_agenda_label']) $sql.= natural_search('a.label', $filters['search_agenda_label']); + } + + // Add also event from emailings. TODO This should be replaced by an automatic event ? May be it's too much for very large emailing. + if (! empty($conf->mailing->enabled) && ! empty($objcon->email) + && (empty($actioncode) || $actioncode == 'AC_OTH_AUTO' || $actioncode == 'AC_EMAILING')) + { + $langs->load("mails"); + + $sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type"; + $sql2.= ", '' as fk_element, '' as elementtype, '' as contact_id"; + $sql2.= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto"; + $sql2.= ", u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action + if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql2.= ", '' as lastname, '' as firstname"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql2.= ", '' as lastname, '' as firstname"; + elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql2.= ", '' as ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql2.= ", '' as ref"; + elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql2.= ", '' as ref"; + $sql2.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u"; + $sql2.= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email. + $sql2.= " AND mc.statut = 1"; + $sql2.= " AND u.rowid = m.fk_user_valid"; + $sql2.= " AND mc.fk_mailing=m.rowid"; + } + + if (!empty($sql) && !empty($sql2)) { + $sql = $sql . " UNION " . $sql2; + } elseif (empty($sql) && !empty($sql2)) { + $sql = $sql2; + } + + //TODO Add limit in nb of results + $sql.= $db->order($sortfield_new, $sortorder); + dol_syslog("company.lib::show_actions_done", LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $i = 0 ; + $num = $db->num_rows($resql); + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + if ($obj->type == 'action') { + $contactaction = new ActionComm($db); + $contactaction->id=$obj->id; + $result = $contactaction->fetchResources(); + if ($result<0) { + dol_print_error($db); + setEventMessage("company.lib::show_actions_done Error fetch ressource", 'errors'); + } + + //if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))"; + //elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))"; + $tododone=''; + if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) $tododone='todo'; + + $histo[$numaction]=array( + 'type'=>$obj->type, + 'tododone'=>$tododone, + 'id'=>$obj->id, + 'datestart'=>$db->jdate($obj->dp), + 'dateend'=>$db->jdate($obj->dp2), + 'note'=>$obj->label, + 'message'=>$obj->message, + 'percent'=>$obj->percent, + + 'userid'=>$obj->user_id, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo, + + 'contact_id'=>$obj->fk_contact, + 'socpeopleassigned' => $contactaction->socpeopleassigned, + 'lastname'=>$obj->lastname, + 'firstname'=>$obj->firstname, + 'fk_element'=>$obj->fk_element, + 'elementtype'=>$obj->elementtype, + // Type of event + 'acode'=>$obj->acode, + 'alabel'=>$obj->alabel, + 'libelle'=>$obj->alabel, // deprecated + 'apicto'=>$obj->apicto + ); + } else { + $histo[$numaction]=array( + 'type'=>$obj->type, + 'tododone'=>'done', + 'id'=>$obj->id, + 'datestart'=>$db->jdate($obj->dp), + 'dateend'=>$db->jdate($obj->dp2), + 'note'=>$obj->label, + 'message'=>$obj->message, + 'percent'=>$obj->percent, + 'acode'=>$obj->acode, + + 'userid'=>$obj->user_id, + 'login'=>$obj->user_login, + 'userfirstname'=>$obj->user_firstname, + 'userlastname'=>$obj->user_lastname, + 'userphoto'=>$obj->user_photo + ); + } + + $numaction++; + $i++; + } + } + else + { + dol_print_error($db); + } + + if (! empty($conf->agenda->enabled) || (! empty($conf->mailing->enabled) && ! empty($objcon->email))) + { + $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60; + + require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + + $formactions=new FormActions($db); + + $actionstatic=new ActionComm($db); + $userstatic=new User($db); + $contactstatic = new Contact($db); + $userGetNomUrlCache = array(); +// $out.='
'; +// if ($objcon && get_class($objcon) == 'Contact' && +// (is_null($filterobj) || get_class($filterobj) == 'Societe')) +// { +// $out.=''; +// } +// else +// { +// $out.=''; +// } +// if ($filterobj && get_class($filterobj) == 'Societe') $out.=''; +// +// +// $out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1); +// +// $out.=''; +// +// $searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1); +// $out.=$searchpicto; +// +// $out.='
'; + + $out.="\n"; + + $out.='\n"; + } + + + if ($noprint) return $out; + else print $out; +} \ No newline at end of file diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 86b4fa82c12..e67f1a934a9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5809,3 +5809,4 @@ div.tabsElem a.tab { include dol_buildpath($path.'/theme/'.$theme.'/dropdown.inc.php', 0); include dol_buildpath($path.'/theme/'.$theme.'/info-box.inc.php', 0); include dol_buildpath($path.'/theme/'.$theme.'/progress.inc.php', 0); +include dol_buildpath($path.'/theme/'.$theme.'/timeline.inc.php', 0); diff --git a/htdocs/theme/eldy/timeline.inc.php b/htdocs/theme/eldy/timeline.inc.php new file mode 100644 index 00000000000..8696d6f449f --- /dev/null +++ b/htdocs/theme/eldy/timeline.inc.php @@ -0,0 +1,142 @@ + + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information + */ + +if (! defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> +/*