123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975 |
- <?php
- /* Copyright (C) 2013-2018 Jean-François FERRY <hello@librethic.io>
- * Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
- * Copyright (C) 2019-2020 Frédéric France <frederic.france@netlogic.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- /**
- * \file core/lib/ticket.lib.php
- * \ingroup ticket
- * \brief This file is a library for Ticket module
- */
- /**
- * Build tabs for admin page
- *
- * @return array
- */
- function ticketAdminPrepareHead()
- {
- global $langs, $conf;
- $langs->load("ticket");
- $h = 0;
- $head = array();
- $head[$h][0] = DOL_URL_ROOT.'/admin/ticket.php';
- $head[$h][1] = $langs->trans("TicketSettings");
- $head[$h][2] = 'settings';
- $h++;
- $head[$h][0] = DOL_URL_ROOT.'/admin/ticket_extrafields.php';
- $head[$h][1] = $langs->trans("ExtraFieldsTicket");
- $head[$h][2] = 'attributes';
- $h++;
- $head[$h][0] = DOL_URL_ROOT.'/admin/ticket_public.php';
- $head[$h][1] = $langs->trans("PublicInterface");
- $head[$h][2] = 'public';
- $h++;
- // Show more tabs from modules
- // Entries must be declared in modules descriptor with line
- //$this->tabs = array(
- // 'entity:+tabname:Title:@ticket:/ticket/mypage.php?id=__ID__'
- //); // to add new tab
- //$this->tabs = array(
- // 'entity:-tabname:Title:@ticket:/ticket/mypage.php?id=__ID__'
- //); // to remove a tab
- complete_head_from_modules($conf, $langs, null, $head, $h, 'ticketadmin');
- complete_head_from_modules($conf, $langs, null, $head, $h, 'ticketadmin', 'remove');
- return $head;
- }
- /**
- * Build tabs for a Ticket object
- *
- * @param Ticket $object Object Ticket
- * @return array Array of tabs
- */
- function ticket_prepare_head($object)
- {
- global $db, $langs, $conf, $user;
- $h = 0;
- $head = array();
- $head[$h][0] = DOL_URL_ROOT.'/ticket/card.php?action=view&track_id='.$object->track_id;
- $head[$h][1] = $langs->trans("Ticket");
- $head[$h][2] = 'tabTicket';
- $h++;
- if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && empty($user->socid) && $conf->societe->enabled) {
- $nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external'));
- $head[$h][0] = DOL_URL_ROOT.'/ticket/contact.php?track_id='.$object->track_id;
- $head[$h][1] = $langs->trans('ContactsAddresses');
- if ($nbContact > 0) {
- $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbContact.'</span>';
- }
- $head[$h][2] = 'contact';
- $h++;
- }
- complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticket');
- // Attached files
- include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- $upload_dir = $conf->ticket->dir_output."/".$object->ref;
- $nbFiles = count(dol_dir_list($upload_dir, 'files'));
- $head[$h][0] = dol_buildpath('/ticket/document.php', 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans("Documents");
- if ($nbFiles > 0) {
- $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbFiles.'</span>';
- }
- $head[$h][2] = 'tabTicketDocument';
- $h++;
- // History
- $ticketViewType = "messaging";
- if (empty($_SESSION['ticket-view-type'])) {
- $_SESSION['ticket-view-type'] = $ticketViewType;
- } else {
- $ticketViewType = $_SESSION['ticket-view-type'];
- }
- if ($ticketViewType == "messaging") {
- $head[$h][0] = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id;
- } else {
- // $ticketViewType == "list"
- $head[$h][0] = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id;
- }
- $head[$h][1] = $langs->trans('Events');
- if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
- $head[$h][1] .= '/';
- $head[$h][1] .= $langs->trans("Agenda");
- }
- $head[$h][2] = 'tabTicketLogs';
- $h++;
- complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticket', 'remove');
- return $head;
- }
- /**
- * Return string with full Url. The file qualified is the one defined by relative path in $object->last_main_doc
- *
- * @param Object $object Object
- * @return string Url string
- */
- function showDirectPublicLink($object)
- {
- global $conf, $langs;
- require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
- $email = CMailFile::getValidAddress($object->origin_email, 2);
- $url = '';
- if ($email) {
- $url = dol_buildpath('/public/ticket/view.php', 3).'?track_id='.$object->track_id.'&email='.$email;
- }
- $out = '';
- if (empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
- $langs->load('errors');
- $out .= '<span class="opacitymedium">'.$langs->trans("ErrorPublicInterfaceNotEnabled").'</span>';
- } else {
- $out .= img_picto('', 'object_globe.png').' <span class="opacitymedium">'.$langs->trans("TicketPublicAccess").'</span><br>';
- if ($url) {
- $out .= '<div class="urllink">';
- $out .= '<input type="text" id="directpubliclink" class="quatrevingtpercentminusx" value="'.$url.'">';
- $out .= '<a href="'.$url.'" target="_blank" rel="noopener">'.img_picto('', 'object_globe.png', 'class="paddingleft"').'</a>';
- $out .= '</div>';
- $out .= ajax_autoselect("directpubliclink", 0);
- } else {
- $out .= '<span class="opacitymedium">'.$langs->trans("TicketNotCreatedFromPublicInterface").'</span>';
- }
- }
- return $out;
- }
- /**
- * Generate a random id
- *
- * @param int $car Length of string to generate key
- * @return string
- */
- function generate_random_id($car = 16)
- {
- $string = "";
- $chaine = "abcdefghijklmnopqrstuvwxyz123456789";
- srand((double) microtime() * 1000000);
- for ($i = 0; $i < $car; $i++) {
- $string .= $chaine[rand() % strlen($chaine)];
- }
- return $string;
- }
- /**
- * Show header for public pages
- *
- * @param string $title Title
- * @param string $head Head array
- * @param int $disablejs More content into html header
- * @param int $disablehead More content into html header
- * @param array $arrayofjs Array of complementary js files
- * @param array $arrayofcss Array of complementary css files
- * @return void
- */
- function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = '', $arrayofcss = '')
- {
- global $user, $conf, $langs, $mysoc;
- top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers
- print '<body id="mainbody" class="publicnewticketform">';
- print '<div class="center">';
- // Define urllogo
- if (!empty($conf->global->TICKET_SHOW_COMPANY_LOGO) || !empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
- // Print logo
- if (!empty($conf->global->TICKET_SHOW_COMPANY_LOGO)) {
- $urllogo = DOL_URL_ROOT.'/theme/common/login_logo.png';
- if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) {
- $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
- } elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) {
- $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$mysoc->logo);
- } elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) {
- $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
- }
- }
- }
- // Output html code for logo
- if ($urllogo || !empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
- print '<div class="backgreypublicpayment">';
- print '<div class="logopublicpayment">';
- if ($urllogo) {
- print '<a href="'.($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE : dol_buildpath('/public/ticket/index.php', 1)).'">';
- print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
- print '>';
- print '</a>';
- }
- if (!empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
- print '<div class="clearboth"></div><strong>'.($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC ? $conf->global->TICKET_PUBLIC_INTERFACE_TOPIC : $langs->trans("TicketSystem")).'</strong>';
- }
- print '</div>';
- if (empty($conf->global->MAIN_HIDE_POWERED_BY)) {
- print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
- }
- print '</div>';
- }
- if (!empty($conf->global->TICKET_IMAGE_PUBLIC_INTERFACE)) {
- print '<div class="backimagepublicticket">';
- print '<img id="idRECRUITMENT_IMAGE_PUBLIC_INTERFACE" src="'.$conf->global->MEMBER_IMAGE_PUBLIC_REGISTRATION.'">';
- print '</div>';
- }
- print '</div>';
- print '<div class="ticketlargemargin">';
- }
- /**
- * 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');
- }
- $histo = array();
- $numaction = 0;
- $now = dol_now();
- $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)) {
- // Search histo on 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 = ".((int) $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 = ".((int) $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 = ".((int) $filterobj->id);
- } elseif (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) {
- $sql .= " AND a.fk_project = ".((int) $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 = ".((int) $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 = ".((int) $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 = ".((int) $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 = ".((int) $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 = ".((int) $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 = ".((int) $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 .= ", null as fk_element, '' as elementtype, null 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
- if ($sql) { // May not be defined if module Agenda is not enabled and mailing module disabled too
- $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);
- }
- }
- // Set $out to sow events
- $out = '';
- if (empty($conf->agenda->enabled)) {
- $langs->loadLangs(array("admin", "errors"));
- $out = info_admin($langs->trans("WarningModuleXDisabledSoYouMayMissEventHere", $langs->transnoentitiesnoconv("Module2400Name")), 0, 0, 'warning');
- }
- 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 .= '<div class="filters-container" >';
- $out .= '<form name="listactionsfilter" class="listactionsfilter" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
- $out .= '<input type="hidden" name="token" value="'.newToken().'">';
- if ($objcon && get_class($objcon) == 'Contact' &&
- (is_null($filterobj) || get_class($filterobj) == 'Societe')) {
- $out .= '<input type="hidden" name="id" value="'.$objcon->id.'" />';
- } else {
- $out .= '<input type="hidden" name="id" value="'.$filterobj->id.'" />';
- }
- if ($filterobj && get_class($filterobj) == 'Societe') {
- $out .= '<input type="hidden" name="socid" value="'.$filterobj->id.'" />';
- }
- $out .= "\n";
- $out .= '<div class="div-table-responsive-no-min">';
- $out .= '<table class="noborder borderbottom centpercent">';
- $out .= '<tr class="liste_titre">';
- $out .= getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', '', $param, '', $sortfield, $sortorder, '')."\n";
- $out .= '<th class="liste_titre"><strong class="hideonsmartphone">'.$langs->trans("Search").' : </strong></th>';
- if ($donetodo) {
- $out .= '<th class="liste_titre"></th>';
- }
- $out .= '<th class="liste_titre">';
- $out .= '<span class="fas fa-square inline-block fawidth30" style=" color: #ddd;" title="'.$langs->trans("ActionType").'"></span>';
- //$out .= img_picto($langs->trans("Type"), 'type');
- $out .= $formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : -1, 0, 0, 1, 'minwidth200imp');
- $out .= '</th>';
- $out .= '<th class="liste_titre maxwidth100onsmartphone">';
- $out .= '<input type="text" class="maxwidth100onsmartphone" name="search_agenda_label" value="'.$filters['search_agenda_label'].'" placeholder="'.$langs->trans("Label").'">';
- $out .= '</th>';
- $out .= '<th class="liste_titre width50 middle">';
- $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
- $out .= $searchpicto;
- $out .= '</th>';
- $out .= '</tr>';
- $out .= '</table>';
- $out .= '</form>';
- $out .= '</div>';
- $out .= "\n";
- $out .= '<ul class="timeline">';
- if ($donetodo) {
- $tmp = '';
- if (get_class($filterobj) == 'Societe') {
- $tmp .= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?action=show_list&socid='.$filterobj->id.'&status=done">';
- }
- $tmp .= ($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : '');
- $tmp .= ($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : '');
- $tmp .= ($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : '');
- //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort");
- if (get_class($filterobj) == 'Societe') {
- $tmp .= '</a>';
- }
- $out .= getTitleFieldOfList($tmp);
- }
- //require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
- //$caction=new CActionComm($db);
- //$arraylist=$caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0), '', 1);
- $actualCycleDate = false;
- foreach ($histo as $key => $value) {
- $actionstatic->fetch($histo[$key]['id']); // TODO Do we need this, we already have a lot of data of line into $histo
- $actionstatic->type_picto = $histo[$key]['apicto'];
- $actionstatic->type_code = $histo[$key]['acode'];
- $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$histo[$key]['id'];
- $tmpa = dol_getdate($histo[$key]['datestart'], false);
- if ($actualCycleDate !== $tmpa['year'].'-'.$tmpa['yday']) {
- $actualCycleDate = $tmpa['year'].'-'.$tmpa['yday'];
- $out .= '<!-- timeline time label -->';
- $out .= '<li class="time-label">';
- $out .= '<span class="timeline-badge-date">';
- $out .= dol_print_date($histo[$key]['datestart'], 'daytext', 'tzuserrel', $langs);
- $out .= '</span>';
- $out .= '</li>';
- $out .= '<!-- /.timeline-label -->';
- }
- $out .= '<!-- timeline item -->'."\n";
- $out .= '<li class="timeline-code-'.strtolower($actionstatic->code).'">';
- $out .= getTicketTimelineIcon($actionstatic, $histo, $key);
- $out .= '<div class="timeline-item">'."\n";
- $out .= '<span class="timeline-header-action">';
- if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'mailing') {
- $out .= '<a class="timeline-btn" href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$histo[$key]['id'].'">'.img_object($langs->trans("ShowEMailing"), "email").' ';
- $out .= $histo[$key]['id'];
- $out .= '</a> ';
- } else {
- $out .= $actionstatic->getNomUrl(1, -1, 'valignmiddle').' ';
- }
- //if ($user->rights->agenda->allactions->read || $actionstatic->authorid == $user->id)
- //{
- // $out.='<a href="'.$url.'" class="timeline-btn" title="'.$langs->trans('Show').'" ><i class="fa fa-calendar" ></i>'.$langs->trans('Show').'</a>';
- //}
- if ($user->rights->agenda->allactions->create ||
- (($actionstatic->authorid == $user->id || $actionstatic->userownerid == $user->id) && $user->rights->agenda->myactions->create)) {
- $out .= '<a class="timeline-btn" href="'.DOL_MAIN_URL_ROOT.'/comm/action/card.php?action=edit&id='.$actionstatic->id.'"><i class="fa fa-pencil" title="'.$langs->trans("Modify").'" ></i></a>';
- }
- $out .= '</span>';
- // Date
- $out .= '<span class="time"><i class="fa fa-clock-o"></i> ';
- $out .= dol_print_date($histo[$key]['datestart'], 'dayhour', 'tzuserrel');
- if ($histo[$key]['dateend'] && $histo[$key]['dateend'] != $histo[$key]['datestart']) {
- $tmpa = dol_getdate($histo[$key]['datestart'], true);
- $tmpb = dol_getdate($histo[$key]['dateend'], true);
- if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
- $out .= '-'.dol_print_date($histo[$key]['dateend'], 'hour', 'tzuserrel');
- } else {
- $out .= '-'.dol_print_date($histo[$key]['dateend'], 'dayhour', 'tzuserrel');
- }
- }
- $late = 0;
- if ($histo[$key]['percent'] == 0 && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
- $late = 1;
- }
- if ($histo[$key]['percent'] == 0 && !$histo[$key]['datestart'] && $histo[$key]['dateend'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
- $late = 1;
- }
- if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && $histo[$key]['dateend'] && $histo[$key]['dateend'] < ($now - $delay_warning)) {
- $late = 1;
- }
- if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && !$histo[$key]['dateend'] && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
- $late = 1;
- }
- if ($late) {
- $out .= img_warning($langs->trans("Late")).' ';
- }
- $out .= "</span>\n";
- // Ref
- $out .= '<h3 class="timeline-header">';
- // Author of event
- $out .= '<span class="messaging-author">';
- if ($histo[$key]['userid'] > 0) {
- if (!isset($userGetNomUrlCache[$histo[$key]['userid']])) { // is in cache ?
- $userstatic->fetch($histo[$key]['userid']);
- $userGetNomUrlCache[$histo[$key]['userid']] = $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, 'firstelselast', '');
- }
- $out .= $userGetNomUrlCache[$histo[$key]['userid']];
- }
- $out .= '</span>';
- // Title
- $out .= ' <span class="messaging-title">';
- if ($actionstatic->code == 'TICKET_MSG') {
- $out .= $langs->trans('TicketNewMessage');
- } elseif ($actionstatic->code == 'TICKET_MSG_PRIVATE') {
- $out .= $langs->trans('TicketNewMessage').' <em>('.$langs->trans('Private').')</em>';
- } else {
- if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'action') {
- $transcode = $langs->trans("Action".$histo[$key]['acode']);
- $libelle = ($transcode != "Action".$histo[$key]['acode'] ? $transcode : $histo[$key]['alabel']);
- $libelle = $histo[$key]['note'];
- $actionstatic->id = $histo[$key]['id'];
- $out .= dol_trunc($libelle, 120);
- }
- if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'mailing') {
- $out .= '<a href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$histo[$key]['id'].'">'.img_object($langs->trans("ShowEMailing"), "email").' ';
- $transcode = $langs->trans("Action".$histo[$key]['acode']);
- $libelle = ($transcode != "Action".$histo[$key]['acode'] ? $transcode : 'Send mass mailing');
- $out .= dol_trunc($libelle, 120);
- }
- }
- $out .= '</span>';
- $out .= '</h3>';
- if (!empty($histo[$key]['message'])
- && $actionstatic->code != 'AC_TICKET_CREATE'
- && $actionstatic->code != 'AC_TICKET_MODIFY'
- ) {
- $out .= '<div class="timeline-body">';
- $out .= $histo[$key]['message'];
- $out .= '</div>';
- }
- // Timeline footer
- $footer = '';
- // Contact for this action
- if (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) {
- $contactList = '';
- foreach ($histo[$key]['socpeopleassigned'] as $cid => $Tab) {
- $contact = new Contact($db);
- $result = $contact->fetch($cid);
- if ($result < 0) {
- dol_print_error($db, $contact->error);
- }
- if ($result > 0) {
- $contactList .= !empty($contactList) ? ', ' : '';
- $contactList .= $contact->getNomUrl(1);
- if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
- if (!empty($contact->phone_pro)) {
- $contactList .= '('.dol_print_phone($contact->phone_pro).')';
- }
- }
- }
- }
- $footer .= $langs->trans('ActionOnContact').' : '.$contactList;
- } elseif (empty($objcon->id) && isset($histo[$key]['contact_id']) && $histo[$key]['contact_id'] > 0) {
- $contact = new Contact($db);
- $result = $contact->fetch($histo[$key]['contact_id']);
- if ($result < 0) {
- dol_print_error($db, $contact->error);
- }
- if ($result > 0) {
- $footer .= $contact->getNomUrl(1);
- if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
- if (!empty($contact->phone_pro)) {
- $footer .= '('.dol_print_phone($contact->phone_pro).')';
- }
- }
- }
- }
- $documents = getTicketActionCommEcmList($actionstatic);
- if (!empty($documents)) {
- $footer .= '<div class="timeline-documents-container">';
- foreach ($documents as $doc) {
- $footer .= '<span id="document_'.$doc->id.'" class="timeline-documents" ';
- $footer .= ' data-id="'.$doc->id.'" ';
- $footer .= ' data-path="'.$doc->filepath.'"';
- $footer .= ' data-filename="'.dol_escape_htmltag($doc->filename).'" ';
- $footer .= '>';
- $filePath = DOL_DATA_ROOT.'/'.$doc->filepath.'/'.$doc->filename;
- $mime = dol_mimetype($filePath);
- $file = $actionstatic->id.'/'.$doc->filename;
- $thumb = $actionstatic->id.'/thumbs/'.substr($doc->filename, 0, strrpos($doc->filename, '.')).'_mini'.substr($doc->filename, strrpos($doc->filename, '.'));
- $doclink = dol_buildpath('document.php', 1).'?modulepart=actions&attachment=0&file='.urlencode($file).'&entity='.$conf->entity;
- $viewlink = dol_buildpath('viewimage.php', 1).'?modulepart=actions&file='.urlencode($thumb).'&entity='.$conf->entity;
- $mimeAttr = ' mime="'.$mime.'" ';
- $class = '';
- if (in_array($mime, array('image/png', 'image/jpeg', 'application/pdf'))) {
- $class .= ' documentpreview';
- }
- $footer .= '<a href="'.$doclink.'" class="btn-link '.$class.'" target="_blank" '.$mimeAttr.' >';
- $footer .= img_mime($filePath).' '.$doc->filename;
- $footer .= '</a>';
- $footer .= '</span>';
- }
- $footer .= '</div>';
- }
- if (!empty($footer)) {
- $out .= '<div class="timeline-footer">'.$footer.'</div>';
- }
- $out .= '</div>'."\n"; // end timeline-item
- $out .= '</li>';
- $out .= '<!-- END timeline item -->';
- $i++;
- }
- $out .= "</ul>\n";
- }
- if ($noprint) {
- return $out;
- } else {
- print $out;
- }
- }
- /**
- * Get timeline icon
- * @param ActionComm $actionstatic actioncomm
- * @param array $histo histo
- * @param int $key key
- * @return string
- */
- function getTicketTimelineIcon($actionstatic, &$histo, $key)
- {
- global $conf, $langs;
- $out = '<!-- timeline icon -->'."\n";
- $iconClass = 'fa fa-comments';
- $img_picto = '';
- $colorClass = '';
- $pictoTitle = '';
- if ($histo[$key]['percent'] == -1) {
- $colorClass = 'timeline-icon-not-applicble';
- $pictoTitle = $langs->trans('StatusNotApplicable');
- } elseif ($histo[$key]['percent'] == 0) {
- $colorClass = 'timeline-icon-todo';
- $pictoTitle = $langs->trans('StatusActionToDo').' (0%)';
- } elseif ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100) {
- $colorClass = 'timeline-icon-in-progress';
- $pictoTitle = $langs->trans('StatusActionInProcess').' ('.$histo[$key]['percent'].'%)';
- } elseif ($histo[$key]['percent'] >= 100) {
- $colorClass = 'timeline-icon-done';
- $pictoTitle = $langs->trans('StatusActionDone').' (100%)';
- }
- if ($actionstatic->code == 'AC_TICKET_CREATE') {
- $iconClass = 'fa fa-ticket';
- } elseif ($actionstatic->code == 'AC_TICKET_MODIFY') {
- $iconClass = 'fa fa-pencilxxx';
- } elseif ($actionstatic->code == 'TICKET_MSG') {
- $iconClass = 'fa fa-comments';
- } elseif ($actionstatic->code == 'TICKET_MSG_PRIVATE') {
- $iconClass = 'fa fa-mask';
- } elseif (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
- if ($actionstatic->type_picto) {
- $img_picto = img_picto('', $actionstatic->type_picto);
- } else {
- if ($actionstatic->type_code == 'AC_RDV') {
- $iconClass = 'fa fa-handshake';
- } elseif ($actionstatic->type_code == 'AC_TEL') {
- $iconClass = 'fa fa-phone';
- } elseif ($actionstatic->type_code == 'AC_FAX') {
- $iconClass = 'fa fa-fax';
- } elseif ($actionstatic->type_code == 'AC_EMAIL') {
- $iconClass = 'fa fa-envelope';
- } elseif ($actionstatic->type_code == 'AC_INT') {
- $iconClass = 'fa fa-shipping-fast';
- } elseif ($actionstatic->type_code == 'AC_OTH_AUTO') {
- $iconClass = 'fa fa-robot';
- } elseif (!preg_match('/_AUTO/', $actionstatic->type_code)) {
- $iconClass = 'fa fa-robot';
- }
- }
- }
- $out .= '<i class="'.$iconClass.' '.$colorClass.'" title="'.$pictoTitle.'">'.$img_picto.'</i>'."\n";
- return $out;
- }
- /**
- * getTicketActionCommEcmList
- *
- * @param ActionComm $object Object ActionComm
- * @return array Array of documents in index table
- */
- function getTicketActionCommEcmList($object)
- {
- global $conf, $db;
- $documents = array();
- $sql = 'SELECT ecm.rowid as id, ecm.src_object_type, ecm.src_object_id, ecm.filepath, ecm.filename';
- $sql .= ' FROM '.MAIN_DB_PREFIX.'ecm_files ecm';
- $sql .= " WHERE ecm.filepath = 'agenda/".((int) $object->id)."'";
- //$sql.= " ecm.src_object_type = '".$db->escape($object->element)."' AND ecm.src_object_id = ".((int) $object->id); // Old version didn't add object_type during upload
- $sql .= ' ORDER BY ecm.position ASC';
- $resql = $db->query($sql);
- if ($resql) {
- if ($db->num_rows($resql)) {
- while ($obj = $db->fetch_object($resql)) {
- $documents[$obj->id] = $obj;
- }
- }
- }
- return $documents;
- }
|