Merge pull request #8338 from Librethic/ticketsup_core

NEW : Ticketsup module integration
This commit is contained in:
Laurent Destailleur 2018-03-11 10:06:27 +01:00 committed by GitHub
commit a331fdd0b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 15234 additions and 0 deletions

666
htdocs/admin/ticketsup.php Normal file
View File

@ -0,0 +1,666 @@
<?php
/* Ticket incident/support management
* Copyright (C) 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file admin/ticketsup.php
* \ingroup ticketsup
* \brief This file is a module setup page
*/
// Dolibarr environment
$res = '';
if (file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../../main.inc.php")) {
$res = include "../../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
// Libraries
require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
require_once "../class/ticketsup.class.php";
require_once "../lib/ticketsup.lib.php";
// Translations
$langs->load("ticketsup@ticketsup");
// Access control
if (!$user->admin) {
accessforbidden();
}
// Parameters
$value = GETPOST('value', 'alpha');
$action = GETPOST('action', 'alpha');
$label = GETPOST('label', 'alpha');
$scandir = GETPOST('scandir', 'alpha');
$type = 'ticketsup';
if ($action == 'updateMask') {
$maskconstticket = GETPOST('maskconstticketsup', 'alpha');
$maskticket = GETPOST('maskticketsup', 'alpha');
if ($maskconstticket) {
$res = dolibarr_set_const($db, $maskconstticket, $maskticket, 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
if (!$error) {
setEventMessage($langs->trans("SetupSaved"));
} else {
setEventMessage($langs->trans("Error"), 'errors');
}
} elseif ($action == 'setmod') {
// TODO Verifier si module numerotation choisi peut etre active
// par appel methode canBeActivated
dolibarr_set_const($db, "TICKETSUP_ADDON", $value, 'chaine', 0, '', $conf->entity);
} elseif ($action == 'setvar') {
include_once DOL_DOCUMENT_ROOT . "/core/lib/files.lib.php";
$notification_email = GETPOST('TICKETS_NOTIFICATION_EMAIL_FROM', 'alpha');
if (!empty($notification_email)) {
$res = dolibarr_set_const($db, 'TICKETS_NOTIFICATION_EMAIL_FROM', $notification_email, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_NOTIFICATION_EMAIL_FROM', '000000', 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
// altairis : differentiate notification email FROM and TO
$notification_email_to = GETPOST('TICKETS_NOTIFICATION_EMAIL_TO', 'alpha');
if (!empty($notification_email_to)) {
$res = dolibarr_set_const($db, 'TICKETS_NOTIFICATION_EMAIL_TO', $notification_email_to, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_NOTIFICATION_EMAIL_TO', '000000', 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$mail_new_ticket = GETPOST('TICKETS_MESSAGE_MAIL_NEW', 'alpha');
if (!empty($mail_new_ticket)) {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_NEW', $mail_new_ticket, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_NEW', $langs->trans('TicketMessageMailNewText'), 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$mail_intro = GETPOST('TICKETS_MESSAGE_MAIL_INTRO', 'alpha');
if (!empty($mail_intro)) {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_INTRO', $mail_intro, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_INTRO', $langs->trans('TicketMessageMailIntroText'), 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$mail_signature = GETPOST('TICKETS_MESSAGE_MAIL_SIGNATURE', 'alpha');
if (!empty($mail_signature)) {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_SIGNATURE', $mail_signature, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_MESSAGE_MAIL_SIGNATURE', $langs->trans('TicketMessageMailSignatureText'), 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$url_interface = GETPOST('TICKETS_URL_PUBLIC_INTERFACE', 'alpha');
if (!empty($mail_signature)) {
$res = dolibarr_set_const($db, 'TICKETS_URL_PUBLIC_INTERFACE', $url_interface, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_URL_PUBLIC_INTERFACE', '', 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$topic_interface = GETPOST('TICKETS_PUBLIC_INTERFACE_TOPIC', 'alpha');
if (!empty($mail_signature)) {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_INTERFACE_TOPIC', $topic_interface, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_INTERFACE_TOPIC', '', 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$text_home = GETPOST('TICKETS_PUBLIC_TEXT_HOME', 'alpha');
if (!empty($mail_signature)) {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_TEXT_HOME', $text_home, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_TEXT_HOME', $langs->trans('TicketPublicInterfaceTextHome'), 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
$text_help = GETPOST('TICKETS_PUBLIC_TEXT_HELP_MESSAGE', 'alpha');
if (!empty($text_help)) {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_TEXT_HELP_MESSAGE', $text_help, 'chaine', 0, '', $conf->entity);
} else {
$res = dolibarr_set_const($db, 'TICKETS_PUBLIC_TEXT_HELP_MESSAGE', $langs->trans('TicketPublicPleaseBeAccuratelyDescribe'), 'chaine', 0, '', $conf->entity);
}
if (!$res > 0) {
$error++;
}
}
if ($action == 'setvarother') {
$param_enable_public_interface = GETPOST('TICKETS_ENABLE_PUBLIC_INTERFACE', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_ENABLE_PUBLIC_INTERFACE', $param_enable_public_interface, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_must_exists = GETPOST('TICKETS_EMAIL_MUST_EXISTS', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_extrafields_public = GETPOST('TICKETS_EXTRAFIELDS_PUBLIC', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_EXTRAFIELDS_PUBLIC', $param_extrafields_public, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_disable_email = GETPOST('TICKETS_DISABLE_ALL_MAILS', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_DISABLE_ALL_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_activate_log_by_email = GETPOST('TICKETS_ACTIVATE_LOG_BY_EMAIL', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_ACTIVATE_LOG_BY_EMAIL', $param_activate_log_by_email, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_show_module_logo = GETPOST('TICKETS_SHOW_MODULE_LOGO', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_SHOW_MODULE_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_notification_also_main_addressemail = GETPOST('TICKETS_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_limit_view = GETPOST('TICKETS_LIMIT_VIEW_ASSIGNED_ONLY', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_LIMIT_VIEW_ASSIGNED_ONLY', $param_limit_view, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
$param_auto_assign = GETPOST('TICKETS_AUTO_ASSIGN_USER_CREATE', 'alpha');
$res = dolibarr_set_const($db, 'TICKETS_AUTO_ASSIGN_USER_CREATE', $param_auto_assign, 'chaine', 0, '', $conf->entity);
if (!$res > 0) {
$error++;
}
}
/*
* View
*/
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
$form = new Form($db);
$help_url = "FR:Module_Ticket";
$page_name = "TicketsupSetup";
llxHeader('', $langs->trans($page_name), $help_url);
// Subheader
$linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php">'
. $langs->trans("BackToModuleList") . '</a>';
print load_fiche_titre($langs->trans($page_name), $linkback);
// Configuration header
$head = ticketsupAdminPrepareHead();
dol_fiche_head(
$head,
'settings',
$langs->trans("Module110120Name"),
0,
"ticketsup@ticketsup"
);
print '<div class="info"><p>' . $langs->trans("TicketsupSetupDictionaries") . ' : <a href="' . dol_buildpath('/admin/dict.php', 1) . '" >' . dol_buildpath('/admin/dict.php', 2) . '</a></p></div>';
print '<p>' . $langs->trans("TicketsupPublicAccess") . ' : <a href="' . dol_buildpath('/ticketsup/public/index.php', 1) . '" target="_blank" >' . dol_buildpath('/ticketsup/public/index.php', 2) . '</a></p>';
//print '<p>'. $langs->trans("TicketsupSetupPage").'</p>';
dol_fiche_end();
/*
* Projects Numbering model
*/
print_titre($langs->trans("TicketSupNumberingModules"));
print '<table class="noborder" width="100%">';
print '<tr class="liste_titre">';
print '<td width="100">' . $langs->trans("Name") . '</td>';
print '<td>' . $langs->trans("Description") . '</td>';
print '<td>' . $langs->trans("Example") . '</td>';
print '<td align="center" width="60">' . $langs->trans("Activated") . '</td>';
print '<td align="center" width="80">' . $langs->trans("ShortInfo") . '</td>';
print "</tr>\n";
clearstatcache();
foreach ($dirmodels as $reldir) {
$dir = dol_buildpath($reldir . "core/modules/ticketsup/");
if (is_dir($dir)) {
$handle = opendir($dir);
if (is_resource($handle)) {
$var = true;
while (($file = readdir($handle)) !== false) {
if (preg_match('/^(mod_.*)\.php$/i', $file, $reg)) {
$file = $reg[1];
$classname = substr($file, 4);
include_once $dir . $file . '.php';
$module = new $file;
// Show modules according to features level
if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
continue;
}
if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
continue;
}
if ($module->isEnabled()) {
$var = !$var;
print '<tr ' . $bc[$var] . '><td>' . $module->name . "</td><td>\n";
print $module->info();
print '</td>';
// Show example of numbering model
print '<td class="nowrap">';
$tmp = $module->getExample();
if (preg_match('/^Error/', $tmp)) {
print '<div class="error">' . $langs->trans($tmp) . '</div>';
} elseif ($tmp == 'NotConfigured') {
print $langs->trans($tmp);
} else {
print $tmp;
}
print '</td>' . "\n";
print '<td align="center">';
if ($conf->global->TICKETSUP_ADDON == 'mod_' . $classname) {
print img_picto($langs->trans("Activated"), 'switch_on');
} else {
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=setmod&amp;value=mod_' . $classname . '" alt="' . $langs->trans("Default") . '">' . img_picto($langs->trans("Disabled"), 'switch_off') . '</a>';
}
print '</td>';
$ticket = new Ticketsup($db);
$ticket->initAsSpecimen();
// Info
$htmltooltip = '';
$htmltooltip .= '' . $langs->trans("Version") . ': <b>' . $module->getVersion() . '</b><br>';
$nextval = $module->getNextValue($mysoc, $ticket);
if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
$htmltooltip .= '' . $langs->trans("NextValue") . ': ';
if ($nextval) {
$htmltooltip .= $nextval . '<br>';
} else {
$htmltooltip .= $langs->trans($module->error) . '<br>';
}
}
print '<td align="center">';
print $form->textwithpicto('', $htmltooltip, 1, 0);
print '</td>';
print '</tr>';
}
}
}
closedir($handle);
}
}
}
print '</table><br>';
if (!$conf->use_javascript_ajax) {
print '<form method="post" action="' . $_SERVER['PHP_SELF'] . '" enctype="multipart/form-data" >';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="setvarother">';
}
print_titre($langs->trans("TicketParamPublicInterface"));
print '<table class="noborder" width="100%">';
// Activate public interface
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsActivatePublicInterface") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_ENABLE_PUBLIC_INTERFACE');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_ENABLE_PUBLIC_INTERFACE", $arrval, $conf->global->TICKETS_ENABLE_PUBLIC_INTERFACE);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsActivatePublicInterfaceHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Check if email exists
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsEmailMustExist") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_EMAIL_MUST_EXISTS');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_EMAIL_MUST_EXISTS", $arrval, $conf->global->TICKETS_EMAIL_MUST_EXISTS);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsEmailMustExistHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Show logo for module
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsShowModuleLogo") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_SHOW_MODULE_LOGO');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_SHOW_MODULE_LOGO", $arrval, $conf->global->TICKETS_SHOW_MODULE_LOGO);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsShowModuleLogoHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Show logo for company
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsShowCompanyLogo") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_SHOW_COMPANY_LOGO');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_SHOW_COMPANY_LOGO", $arrval, $conf->global->TICKETS_SHOW_COMPANY_LOGO);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsShowCompanyLogoHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Display extrafields into public interface
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsShowExtrafieldsIntoPublicArea") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_EXTRAFIELDS_PUBLIC');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_EXTRAFIELDS_PUBLIC", $arrval, $conf->global->TICKETS_EXTRAFIELDS_PUBLIC);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsShowExtrafieldsIntoPublicAreaHelp"), 1, 'help');
print '</td>';
print '</tr>';
print '</table><br>';
print_titre($langs->trans("TicketParams"));
print '<table class="noborder" width="100%">';
// Activate email notifications
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsDisableEmail") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_DISABLE_ALL_MAILS');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_DISABLE_ALL_MAILS", $arrval, $conf->global->TICKETS_DISABLE_ALL_MAILS);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsDisableEmailHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Activate log by email
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsLogEnableEmail") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_ACTIVATE_LOG_BY_EMAIL');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_ACTIVATE_LOG_BY_EMAIL", $arrval, $conf->global->TICKETS_ACTIVATE_LOG_BY_EMAIL);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsLogEnableEmailHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Also send to main email address
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsEmailAlsoSendToMainAddress") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_NOTIFICATION_ALSO_MAIN_ADDRESS');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKETS_NOTIFICATION_ALSO_MAIN_ADDRESS);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Limiter la vue des tickets à ceux assignés à l'utilisateur
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsLimitViewAssignedOnly") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_LIMIT_VIEW_ASSIGNED_ONLY');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_LIMIT_VIEW_ASSIGNED_ONLY", $arrval, $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsLimitViewAssignedOnlyHelp"), 1, 'help');
print '</td>';
print '</tr>';
if (!$conf->use_javascript_ajax) {
print '<tr class="impair"><td colspan="3" align="center"><input type="submit" class="button" value="' . $langs->trans("Save") . '"></td>';
print '</tr>';
}
// Auto assign ticket at user who created it
print '<tr class="pair"><td width="70%">' . $langs->trans("TicketsAutoAssignTicket") . '</td>';
print '<td align="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKETS_AUTO_ASSIGN_USER_CREATE');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("TICKETS_AUTO_ASSIGN_USER_CREATE", $arrval, $conf->global->TICKETS_AUTO_ASSIGN_USER_CREATE);
}
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, 'help');
print '</td>';
print '</tr>';
print '</table><br>';
if (!$conf->use_javascript_ajax) {
print '</form>';
}
// Admin var of module
print_titre($langs->trans("TicketParamMail"));
print '<table class="noborder" width="100%">';
print '<form method="post" action="' . $_SERVER['PHP_SELF'] . '" enctype="multipart/form-data" >';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="setvar">';
print '<tr class="liste_titre">';
print '<td colspan="3">' . $langs->trans("Email") . '</td>';
print "</tr>\n";
if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) {
print '<tr>';
print '<td colspan="3"><div class="info">' . $langs->trans("TicketSupCkEditorEmailNotActivated") . '</div></td>';
print "</tr>\n";
}
// Email d'envoi des notifications
print '<tr class="pair"><td>' . $langs->trans("TicketEmailNotificationFrom") . '</td>';
print '<td align="left">';
print '<input type="text" name="TICKETS_NOTIFICATION_EMAIL_FROM" value="' . $conf->global->TICKETS_NOTIFICATION_EMAIL_FROM . '" size="20" ></td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketEmailNotificationFromHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Email de réception des notifications
print '<tr class="pair"><td>' . $langs->trans("TicketEmailNotificationTo") . '</td>';
print '<td align="left">';
print '<input type="text" name="TICKETS_NOTIFICATION_EMAIL_TO" value="' . (!empty($conf->global->TICKETS_NOTIFICATION_EMAIL_TO) ? $conf->global->TICKETS_NOTIFICATION_EMAIL_TO : $conf->global->TICKETS_NOTIFICATION_EMAIL_FROM) . '" size="20" ></td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help');
print '</td>';
print '</tr>';
// Texte de création d'un ticket
$mail_mesg_new = $conf->global->TICKETS_MESSAGE_MAIL_NEW ? $conf->global->TICKETS_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody');
print '<tr><td>' . $langs->trans("TicketNewEmailBodyLabel") . '</label>';
print '</td><td>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$doleditor = new DolEditor('TICKETS_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70);
$doleditor->Create();
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketNewEmailBodyHelp"), 1, 'help');
print '</td></tr>';
// Texte d'introduction
$mail_intro = $conf->global->TICKETS_MESSAGE_MAIL_INTRO ? $conf->global->TICKETS_MESSAGE_MAIL_INTRO : $langs->trans('TicketMessageMailIntroText');
print '<tr><td>' . $langs->trans("TicketMessageMailIntroLabelAdmin") . '</label>';
print '</td><td>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$doleditor = new DolEditor('TICKETS_MESSAGE_MAIL_INTRO', $mail_intro, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70);
$doleditor->Create();
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketMessageMailIntroHelpAdmin"), 1, 'help');
print '</td></tr>';
// Texte de signature
$mail_signature = $conf->global->TICKETS_MESSAGE_MAIL_SIGNATURE ? $conf->global->TICKETS_MESSAGE_MAIL_SIGNATURE : $langs->trans('TicketMessageMailSignatureText');
print '<tr><td>' . $langs->trans("TicketMessageMailSignatureLabelAdmin") . '</label>';
print '</td><td>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$doleditor = new DolEditor('TICKETS_MESSAGE_MAIL_SIGNATURE', $mail_signature, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70);
$doleditor->Create();
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelpAdmin"), 1, 'help');
print '</td></tr>';
print '<tr class="liste_titre">';
print '<td colspan="3">' . $langs->trans("PublicInterface") . '</td>';
print "</tr>\n";
// Url public interface
$url_interface = $conf->global->TICKETS_URL_PUBLIC_INTERFACE;
print '<tr><td>' . $langs->trans("TicketUrlPublicInterfaceLabelAdmin") . '</label>';
print '</td><td>';
print '<input type="text" name="TICKETS_URL_PUBLIC_INTERFACE" value="' . $conf->global->TICKETS_URL_PUBLIC_INTERFACE . '" size="40" ></td>';
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help');
print '</td></tr>';
// Interface topic
$url_interface = $conf->global->TICKETS_PUBLIC_INTERFACE_TOPIC;
print '<tr><td>' . $langs->trans("TicketPublicInterfaceTopicLabelAdmin") . '</label>';
print '</td><td>';
print '<input type="text" name="TICKETS_PUBLIC_INTERFACE_TOPIC" value="' . $conf->global->TICKETS_PUBLIC_INTERFACE_TOPIC . '" size="40" ></td>';
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTopicHelp"), 1, 'help');
print '</td></tr>';
// Texte d'accueil homepage
$public_text_home = $conf->global->TICKETS_PUBLIC_TEXT_HOME ? $conf->global->TICKETS_PUBLIC_TEXT_HOME : $langs->trans('TicketPublicInterfaceTextHome');
print '<tr><td>' . $langs->trans("TicketPublicInterfaceTextHomeLabelAdmin") . '</label>';
print '</td><td>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$doleditor = new DolEditor('TICKETS_PUBLIC_TEXT_HOME', $public_text_home, '100%', 180, 'dolibarr_notes', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
$doleditor->Create();
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHomeHelpAdmin"), 1, 'help');
print '</td></tr>';
// Texte d'aide à la saisie du message
$public_text_help_message = $conf->global->TICKETS_PUBLIC_TEXT_HELP_MESSAGE ? $conf->global->TICKETS_PUBLIC_TEXT_HELP_MESSAGE : $langs->trans('TicketPublicPleaseBeAccuratelyDescribe');
print '<tr><td>' . $langs->trans("TicketPublicInterfaceTextHelpMessageLabelAdmin") . '</label>';
print '</td><td>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$doleditor = new DolEditor('TICKETS_PUBLIC_TEXT_HELP_MESSAGE', $public_text_help_message, '100%', 180, 'dolibarr_notes', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
$doleditor->Create();
print '</td>';
print '<td align="center">';
print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help');
print '</td></tr>';
print '<tr class="impair"><td colspan="3" align="center"><input type="submit" class="button" value="' . $langs->trans("Save") . '"></td>';
print '</tr>';
print '</table><br>';
print '</form>';
llxFooter();
$db->close();

View File

@ -0,0 +1,127 @@
<?php
/* Ticket incident/support management
* Copyright (C) 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/admin/ticketsup_extrafields.php
* \ingroup ticketsup
* \brief Page to setup extra fields of ticket
*/
$res = '';
if (file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../../main.inc.php")) {
$res = include "../../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once '../lib/ticketsup.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
$langs->load("ticketsup@ticketsup");
$langs->load("admin");
$extrafields = new ExtraFields($db);
$form = new Form($db);
// List of supported format
$tmptype2label = ExtraFields::$type2label;
$type2label = array('');
foreach ($tmptype2label as $key => $val) {
$type2label[$key] = $langs->trans($val);
}
$action = GETPOST('action', 'alpha');
$attrname = GETPOST('attrname', 'alpha');
$elementtype = 'ticketsup'; //Must be the $table_element of the class that manage extrafield
if (!$user->admin) {
accessforbidden();
}
/*
* Actions
*/
if (versioncompare(versiondolibarrarray(), array(3, 5, 0)) > 0) {
include DOL_DOCUMENT_ROOT . '/core/actions_extrafields.inc.php';
} elseif (versioncompare(versiondolibarrarray(), array(3, 4, 0)) > 0) {
include DOL_DOCUMENT_ROOT . '/core/admin_extrafields.inc.php';
}
/*
* View
*/
$textobject = $langs->transnoentitiesnoconv("TicketSup");
$help_url = "FR:Module_Ticket";
$page_name = "TicketsupSetup";
llxHeader('', $langs->trans($page_name), $help_url);
$linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php">' . $langs->trans("BackToModuleList") . '</a>';
print load_fiche_titre($langs->trans("TicketsupSetup"), $linkback, 'setup');
$head = ticketsupAdminPrepareHead();
dol_fiche_head(
$head,
'attributes',
$langs->trans("Module110120Name"),
0,
"ticketsup@ticketsup"
);
require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php';
dol_fiche_end();
// Buttons
if ($action != 'create' && $action != 'edit') {
print '<div class="tabsAction">';
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?action=create\">" . $langs->trans("NewAttribute") . '</a></div>';
print "</div>";
}
/* ************************************************************************** */
/* */
/* Creation d'un champ optionnel */
/* */
/* ************************************************************************** */
if ($action == 'create') {
print "<br>";
print_titre($langs->trans('NewAttribute'));
include DOL_DOCUMENT_ROOT . '/core/tpl/admin_extrafields_add.tpl.php';
}
/* ************************************************************************** */
/* */
/* Edition d'un champ optionnel */
/* */
/* ************************************************************************** */
if ($action == 'edit' && !empty($attrname)) {
print "<br>";
print_titre($langs->trans("FieldEdition", $attrname));
include DOL_DOCUMENT_ROOT . '/core/tpl/admin_extrafields_edit.tpl.php';
}
llxFooter();
$db->close();

View File

@ -0,0 +1,189 @@
<?php
/* Module descriptor for ticket system
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/core/boxes/ticketsup_latest.php
* \ingroup ticketsup
* \brief This box shows latest UNREAD tickets
*/
require_once DOL_DOCUMENT_ROOT . "/core/boxes/modules_boxes.php";
/**
* Class to manage the box
*/
class box_last_modified_ticketsup extends ModeleBoxes
{
public $boxcode = "box_last_modified_ticketsup";
public $boximg = "ticketsup@ticketsup";
public $boxlabel;
public $depends = array("ticketsup");
public $db;
public $param;
public $info_box_head = array();
public $info_box_contents = array();
/**
* Constructor
*/
public function __construct()
{
global $langs;
$langs->load("boxes");
$this->boxlabel = $langs->transnoentitiesnoconv("BoxLastModifiedTicketsup");
}
/**
* Load data into info_box_contents array to show array later.
*
* @param int $max Maximum number of records to load
* @return void
*/
public function loadBox($max = 5)
{
global $conf, $user, $langs, $db;
$this->max = $max;
dol_include_once("/ticketsup/class/ticketsup.class.php");
$text = $langs->trans("BoxLastModifiedTicketsupDescription", $max);
$this->info_box_head = array(
'text' => $text,
'limit' => dol_strlen($text)
);
$this->info_box_contents[0][0] = array('td' => 'align="left"',
'text' => $langs->trans("BoxLastModifiedTicketsupContent"));
if ($user->rights->ticketsup->read) {
$sql = "SELECT t.rowid as id, t.ref, t.track_id, t.fk_soc, t.fk_user_create, t.fk_user_assign, t.subject, t.message, t.fk_statut, t.type_code, t.category_code, t.severity_code, t.datec, t.date_read, t.date_close, t.origin_email ";
$sql.= ", type.label as type_label, category.label as category_label, severity.label as severity_label";
$sql.= ", s.nom as company_name";
$sql.= " FROM ".MAIN_DB_PREFIX."ticketsup as t";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticketsup_type as type ON type.code=t.type_code";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticketsup_category as category ON category.code=t.category_code";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticketsup_severity as severity ON severity.code=t.severity_code";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=t.fk_soc";
$sql.= " WHERE t.entity = ".$conf->entity;
// $sql.= " AND e.rowid = er.fk_event";
//if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($user->societe_id) {
$sql.= " AND t.fk_soc= ".$user->societe_id;
}
$sql.= " ORDER BY t.tms DESC, t.rowid DESC ";
$sql.= $db->plimit($max, 0);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$now=gmmktime();
$i = 0;
while ($i < $num) {
$objp = $db->fetch_object($resql);
$datec=$db->jdate($objp->datec);
$dateterm=$db->jdate($objp->fin_validite);
$dateclose=$db->jdate($objp->date_cloture);
$late = '';
$ticketsup = new Ticketsup($this->db);
$r=0;
// Picto
$this->info_box_contents[$i][0] = array(
'td' => 'align="left" width="16"',
'logo' => $this->boximg,
'url' => dol_buildpath("/ticketsup/card.php?track_id=".$objp->track_id, 1));
$r++;
// Id
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'text' => $objp->ref,
'url' => dol_buildpath("/ticketsup/card.php?track_id=".$objp->track_id, 1));
$r++;
// Subject
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'text' => $objp->subject, // Some event have no ref
'url' => dol_buildpath("/ticketsup/card.php?track_id=".$objp->track_id, 1));
$r++;
// Customer
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'logo' => ($objp->fk_soc>0?'company':''),
'text' => ($objp->company_name?$objp->company_name:$objp->origin_email),
'url' => ($objp->fk_soc>0?DOL_URL_ROOT."/comm/card.php?socid=".$objp->fk_soc:'')
);
$r++;
// Date creation
$this->info_box_contents[$i][$r] = array(
'td' => 'align="right"',
'text' => dol_print_date($db->idate($objp->datec), 'dayhour')
);
$r++;
// Statut
$ticketstat = new Ticketsup($this->db);
$ticketstat->fk_statut = $objp->fk_statut;
$this->info_box_contents[$i][$r] = array(
'td' => 'align="right"',
'text' => $ticketstat->getLibStatut(3)
);
$r++;
$i++;
}
if ($num==0) {
$this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("BoxLastModifiedTicketsupNoRecordedTickets"));
}
} else {
dol_print_error($db);
}
} else {
$this->info_box_contents[0][0] = array('td' => 'align="left"',
'text' => $langs->trans("ReadPermissionNotAllowed"));
}
}
/**
* Method to show box
*
* @param array $head Array with properties of box title
* @param array $contents Array with properties of box lines
* @param int $nooutput No print, only return string
* @return string
*/
function showBox($head = null, $contents = null, $nooutput=0)
{
parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
}
}

View File

@ -0,0 +1,189 @@
<?php
/* Module descriptor for ticket system
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/core/boxes/ticketsup_latest.php
* \ingroup ticketsup
* \brief This box shows latest tickets
*/
require_once DOL_DOCUMENT_ROOT . "/core/boxes/modules_boxes.php";
/**
* Class to manage the box
*/
class box_last_ticketsup extends ModeleBoxes
{
public $boxcode = "box_last_ticketsup";
public $boximg = "ticketsup@ticketsup";
public $boxlabel;
public $depends = array("ticketsup");
public $db;
public $param;
public $info_box_head = array();
public $info_box_contents = array();
/**
* Constructor
*/
public function __construct()
{
global $langs;
$langs->load("boxes");
$this->boxlabel = $langs->transnoentitiesnoconv("BoxLastTicketsup");
}
/**
* Load data into info_box_contents array to show array later.
*
* @param int $max Maximum number of records to load
* @return void
*/
public function loadBox($max = 5)
{
global $conf, $user, $langs, $db;
$this->max = $max;
dol_include_once("/ticketsup/class/ticketsup.class.php");
$text = $langs->trans("BoxLastTicketsupDescription", $max);
$this->info_box_head = array(
'text' => $text,
'limit' => dol_strlen($text),
);
$this->info_box_contents[0][0] = array('td' => 'align="left"',
'text' => $langs->trans("BoxLastTicketsupContent"));
if ($user->rights->ticketsup->read) {
$sql = "SELECT t.rowid as id, t.ref, t.track_id, t.fk_soc, t.fk_user_create, t.fk_user_assign, t.subject, t.message, t.fk_statut, t.type_code, t.category_code, t.severity_code, t.datec, t.date_read, t.date_close, t.origin_email ";
$sql .= ", type.label as type_label, category.label as category_label, severity.label as severity_label";
$sql .= ", s.nom as company_name";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup as t";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_type as type ON type.code=t.type_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_category as category ON category.code=t.category_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_severity as severity ON severity.code=t.severity_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid=t.fk_soc";
$sql .= " WHERE t.entity = " . $conf->entity;
// $sql.= " AND e.rowid = er.fk_event";
//if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($user->societe_id) {
$sql .= " AND t.fk_soc= " . $user->societe_id;
}
//$sql.= " AND t.fk_statut > 9";
$sql .= " ORDER BY t.datec DESC, t.rowid DESC ";
$sql .= $db->plimit($max, 0);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$now = gmmktime();
$i = 0;
while ($i < $num) {
$objp = $db->fetch_object($resql);
$datec = $db->jdate($objp->datec);
$dateterm = $db->jdate($objp->fin_validite);
$dateclose = $db->jdate($objp->date_cloture);
$late = '';
$ticketsup = new Ticketsup($this->db);
$r = 0;
// Picto
$this->info_box_contents[$i][0] = array(
'td' => 'align="left" width="16"',
'logo' => $this->boximg,
'url' => dol_buildpath("/ticketsup/card.php?track_id=" . $objp->track_id, 1));
$r++;
// Id
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'text' => $objp->ref,
'url' => dol_buildpath("/ticketsup/card.php?track_id=" . $objp->track_id, 1));
$r++;
// Subject
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'text' => $objp->subject, // Some event have no ref
'url' => dol_buildpath("/ticketsup/card.php?track_id=" . $objp->track_id, 1));
$r++;
// Customer
$this->info_box_contents[$i][$r] = array(
'td' => 'align="left"',
'logo' => ($objp->fk_soc > 0 ? 'company' : ''),
'text' => ($objp->company_name ? $objp->company_name : $objp->origin_email),
'url' => ($objp->fk_soc > 0 ? DOL_URL_ROOT . "/comm/card.php?socid=" . $objp->fk_soc : ''),
);
$r++;
// Date creation
$this->info_box_contents[$i][$r] = array(
'td' => 'align="right"',
'text' => dol_print_date($db->idate($objp->datec), 'dayhour'),
);
$r++;
// Statut
$ticketstat = new Ticketsup($this->db);
$ticketstat->fk_statut = $objp->fk_statut;
$this->info_box_contents[$i][$r] = array(
'td' => 'align="right"',
'text' => $ticketstat->getLibStatut(3),
);
$r++;
$i++;
}
if ($num == 0) {
$this->info_box_contents[$i][0] = array('td' => 'align="center"', 'text' => $langs->trans("BoxLastTicketsupNoRecordedTickets"));
}
} else {
dol_print_error($db);
}
} else {
$this->info_box_contents[0][0] = array('td' => 'align="left"',
'text' => $langs->trans("ReadPermissionNotAllowed"));
}
}
/**
* Method to show box
*
* @param array $head Array with properties of box title
* @param array $contents Array with properties of box lines
* @param int $nooutput No print, only return string
* @return string
*/
function showBox($head = null, $contents = null, $nooutput=0)
{
parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,200 @@
<?php
/* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file lib/ticketsup.lib.php
* \ingroup ticketsup
* \brief This file is an example module library
* Put some comments here
*/
function ticketsupAdminPrepareHead()
{
global $langs, $conf;
$langs->load("ticketsup@ticketsup");
$h = 0;
$head = array();
$head[$h][0] = dol_buildpath("/ticketsup/admin/admin_ticketsup.php", 1);
$head[$h][1] = $langs->trans("TicketSupSettings");
$head[$h][2] = 'settings';
$h++;
$head[$h][0] = dol_buildpath("/ticketsup/admin/ticketsup_extrafields.php", 1);
$head[$h][1] = $langs->trans("ExtraFieldsTicketSup");
$head[$h][2] = 'attributes';
$h++;
$head[$h][0] = dol_buildpath("/ticketsup/admin/about.php", 1);
$head[$h][1] = $langs->trans("About");
$head[$h][2] = 'about';
$h++;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
//$this->tabs = array(
// 'entity:+tabname:Title:@ticketsup:/ticketsup/mypage.php?id=__ID__'
//); // to add new tab
//$this->tabs = array(
// 'entity:-tabname:Title:@ticketsup:/ticketsup/mypage.php?id=__ID__'
//); // to remove a tab
complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticketsupadmin');
return $head;
}
/**
* \file htdocs/hosting/lib/hosting.lib.php
* \brief Ensemble de fonctions de base pour le module hosting
* \ingroup business
* \version $Id$
*/
function ticketsup_prepare_head($object)
{
global $db, $langs, $conf, $user;
$h = 0;
$head = array();
$head[$h][0] = dol_buildpath('/ticketsup/card.php', 1) . '?action=view&track_id=' . $object->track_id;
$head[$h][1] = $langs->trans("Card");
$head[$h][2] = 'tabTicketsup';
$h++;
if (empty($user->socid)) {
$head[$h][0] = dol_buildpath('/ticketsup/contacts.php', 1) . '?track_id=' . $object->track_id;
$head[$h][1] = $langs->trans('Contacts');
$head[$h][2] = 'tabTicketContacts';
$h++;
}
complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticketsup');
// Attached files
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
$upload_dir = $conf->ticketsup->dir_output . "/" . $object->track_id;
$nbFiles = count(dol_dir_list($upload_dir, 'files'));
$head[$h][0] = dol_buildpath('/ticketsup/document.php', 1) . '?track_id=' . $object->track_id;
$head[$h][1] = $langs->trans("Documents");
if ($nbFiles > 0) {
$head[$h][1] .= ' <span class="badge">' . $nbFiles . '</span>';
}
$head[$h][2] = 'tabTicketDocument';
$h++;
// History
$head[$h][0] = dol_buildpath('/ticketsup/history.php', 1) . '?track_id=' . $object->track_id;
$head[$h][1] = $langs->trans('TicketHistory');
$head[$h][2] = 'tabTicketLogs';
$h++;
complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticketsup','remove');
return $head;
}
/**
* Generate a random id
*
* @param string $car Char to generate key
* @return void
*/
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); // Show html headers
print '<body id="mainbody" class="publicnewticketform" style="margin-top: 10px;">';
if (! empty($conf->global->TICKETS_SHOW_COMPANY_LOGO)) {
showlogo();
}
print '<div style="margin-left: 50px; margin-right: 50px;">';
}
/**
* Show footer for new member
*
* @return void
*/
function llxFooterTicket()
{
print '</div>';
printCommonFooter('public');
dol_htmloutput_events();
print "</body>\n";
print "</html>\n";
}
/**
* Show logo
*
* @return void
*/
function showlogo()
{
global $conf, $langs, $mysoc;
// Print logo
$urllogo = DOL_URL_ROOT . '/theme/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?cache=1&amp;modulepart=companylogo&amp;file=' . urlencode('thumbs/' . $mysoc->logo_small);
} elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output . '/logos/' . $mysoc->logo)) {
$urllogo = DOL_URL_ROOT . '/viewimage.php?cache=1&amp;modulepart=companylogo&amp;file=' . urlencode($mysoc->logo);
$width = 128;
} elseif (is_readable(DOL_DOCUMENT_ROOT . '/theme/dolibarr_logo.png')) {
$urllogo = DOL_URL_ROOT . '/theme/dolibarr_logo.png';
}
print '<center>';
print '<a href="' . ($conf->global->TICKETS_URL_PUBLIC_INTERFACE ? $conf->global->TICKETS_URL_PUBLIC_INTERFACE : dol_buildpath('/ticketsup/public/index.php', 1)) . '"><img alt="Logo" id="logosubscribe" title="" src="' . $urllogo . '" style="max-width: 440px" /></a><br>';
print '<strong>' . ($conf->global->TICKETS_PUBLIC_INTERFACE_TOPIC ? $conf->global->TICKETS_PUBLIC_INTERFACE_TOPIC : $langs->trans("TicketSystem")) . '</strong>';
print '</center><br>';
}

View File

@ -0,0 +1,367 @@
<?php
/* Module descriptor for ticket system
* Copyright (C) - 2013-2018 Jean-François FERRY <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \defgroup ticketsup Ticketsup module
* \brief Ticketsup module descriptor.
* \file core/modules/modTicketsup.class.php
* \ingroup ticketsup
* \brief Description and activation file for module Ticketsup
*/
require_once DOL_DOCUMENT_ROOT . "/core/modules/DolibarrModules.class.php";
/**
* Description and activation class for module Ticketsup
*/
class modTicketsup extends DolibarrModules
{
/**
* Constructor. Define names, constants, directories, boxes, permissions
*
* @param DoliDB $db Database handler
*/
public function __construct($db)
{
global $langs, $conf;
$this->db = $db;
// Id for module (must be unique).
// Use a free id here
// (See in Home -> System information -> Dolibarr for list of used modules id).
$this->numero = 110120;
// Key text used to identify module (for permissions, menus, etc...)
$this->rights_class = 'ticketsup';
$this->editor_name = "Dolibarr";
$this->editor_web = "https://dolibrr.org";
// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
// It is used to group modules in module setup page
$this->family = "crm";
// Module position in the family
$this->module_position = 500;
// Module label (no space allowed)
// used if translation string 'ModuleXXXName' not found
// (where XXX is value of numeric property 'numero' of module)
$this->name = preg_replace('/^mod/i', '', get_class($this));
// Module description
// used if translation string 'ModuleXXXDesc' not found
// (where XXX is value of numeric property 'numero' of module)
$this->description = "Incident/support ticket management";
// Possible values for version are: 'development', 'experimental' or version
$this->version = 'experimental';
// Key used in llx_const table to save module status enabled/disabled
// (where MYMODULE is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_' . strtoupper($this->name);
// Where to store the module in setup page
// (0=common,1=interface,2=others,3=very specific)
$this->special = 2;
// Name of image file used for this module.
// If file is in theme/yourtheme/img directory under name object_pictovalue.png
// use this->picto='pictovalue'
// If file is in module/img directory under name object_pictovalue.png
// use this->picto='pictovalue@module'
$this->picto = 'ticketsup@ticketsup'; // mypicto@ticketsup
// Defined all module parts (triggers, login, substitutions, menus, css, etc...)
// for default path (eg: /ticketsup/core/xxxxx) (0=disable, 1=enable)
// for specific path of parts (eg: /ticketsup/core/modules/barcode)
// for specific css file (eg: /ticketsup/css/ticketsup.css.php)
$this->module_parts = array(
// Set this to 1 if module has its own trigger directory
'triggers' => 1,
// Set this to 1 if module has its own login method directory
//'login' => 0,
// Set this to 1 if module has its own substitution function file
//'substitutions' => 0,
// Set this to 1 if module has its own menus handler directory
//'menus' => 0,
// Set this to 1 if module has its own barcode directory
//'barcode' => 0,
// Set this to 1 if module has its own models directory
'models' => 1,
// Set this to relative path of css if module has its own css file
'css' => '/ticketsup/css/ticketsup.css',
// Set here all hooks context managed by module
'hooks' => array('admin')
// Set here all workflow context managed by module
//'workflow' => array('order' => array('WORKFLOW_ORDER_AUTOCREATE_INVOICE'))
);
// Data directories to create when module is enabled.
// Example: this->dirs = array("/ticketsup/temp");
$this->dirs = array();
// Config pages. Put here list of php pages
// stored into ticketsup/admin directory, used to setup module.
$this->config_page_url = array("ticketsup.php");
// Dependencies
// List of modules id that must be enabled if this module is enabled
$this->depends = array();
// List of modules id to disable if this one is disabled
$this->requiredby = array();
// Minimum version of PHP required by module
$this->phpmin = array(5, 3);
$this->langfiles = array("ticketsup");
// Constants
// List of particular constants to add when module is enabled
// (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
// Example:
$this->const = array();
$this->const[1] = array('TICKETS_ENABLE_PUBLIC_INTERFACE', 'chaine', '1', 'Enable ticket public interface');
$this->const[2] = array('TICKETSUP_ADDON', 'chaine', 'mod_ticketsup_simple', 'Ticketsup ref module');
$this->tabs = array(
'thirdparty:+ticketsup:Tickets:@ticketsup:$user->rights->ticketsup->read:/ticketsup/list.php?socid=__ID__',
'project:+ticketsup:Tickets:@ticketsup:$user->rights->ticketsup->read:/ticketsup/list.php?projectid=__ID__',
);
// Dictionnaries
if (! isset($conf->ticketsup->enabled)) {
$conf->ticketsup=new stdClass();
$conf->ticketsup->enabled=0;
}
$this->dictionaries = array(
'langs' => 'ticketsup@ticketsup',
'tabname' => array(MAIN_DB_PREFIX . "c_ticketsup_type", MAIN_DB_PREFIX . "c_ticketsup_category", MAIN_DB_PREFIX . "c_ticketsup_severity"),
'tablib' => array("TicketsupDictType", "TicketsupDictCategory", "TicketsupDictSeverity"),
'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticketsup_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticketsup_category as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticketsup_severity as f'),
'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC"),
'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
'tabrowid' => array("rowid", "rowid", "rowid"),
'tabcond' => array($conf->ticketsup->enabled, $conf->ticketsup->enabled, $conf->ticketsup->enabled),
);
// Boxes
// Add here list of php file(s) stored in core/boxes that contains class to show a box.
$this->boxes = array(); // Boxes list
$r = 0;
// Example:
$this->boxes[$r][1] = "box_last_ticketsup@ticketsup";
$r++;
$this->boxes[$r][1] = "box_last_modified_ticketsup@ticketsup";
$r++;
// Permissions
$this->rights = array(); // Permission array used by this module
$r = 0;
$r++;
$this->rights[$r][0] = 110120; // id de la permission
$this->rights[$r][1] = "Créer un ticket"; // libelle de la permission
$this->rights[$r][2] = 'c'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'create';
$r++;
$this->rights[$r][0] = 110121; // id de la permission
$this->rights[$r][1] = "Lire les tickets"; // libelle de la permission
$this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 1; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'read';
$r++;
$this->rights[$r][0] = 110122; // id de la permission
$this->rights[$r][1] = "Modifier les tickets"; // libelle de la permission
$this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'write';
$r++;
$this->rights[$r][0] = 110123; // id de la permission
$this->rights[$r][1] = "Supprimer les tickets"; // libelle de la permission
$this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'delete';
$r++;
$this->rights[$r][0] = 110124; // id de la permission
$this->rights[$r][1] = "Gérer les tickets"; // libelle de la permission
//$this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'manage';
$r++;
$this->rights[$r][0] = 110125; // id de la permission
$this->rights[$r][1] = 'Voir tous les tickets (non effectif pour les utilisateurs externes, toujours limités au tiers dont ils dépendent)'; // libelle de la permission
$this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour)
$this->rights[$r][3] = 0; // La permission est-elle une permission par defaut
$this->rights[$r][4] = 'view';
$this->rights[$r][5] = 'all';
// Main menu entries
$this->menus = array(); // List of menus to add
$r = 0;
$this->menu[$r] = array('fk_menu' => 0, // Put 0 if this is a top menu
'type' => 'top', // This is a Top menu entry
'titre' => 'Ticket',
'mainmenu' => 'ticketsup',
'leftmenu' => '1', // Use 1 if you also want to add left menu entries using this descriptor.
'url' => '/ticketsup/index.php',
'langs' => 'ticketsup@ticketsup', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position' => 100,
'enabled' => '1', // Define condition to show or hide menu entry. Use '$conf->ticketsup->enabled' if entry must be visible if module is enabled.
'perms' => '$user->rights->ticketsup->read', // Use 'perms'=>'$user->rights->ticketsup->level1->level2' if you want your menu with a permission rules
'target' => '',
'user' => 2); // 0=Menu for internal users, 1=external users, 2=both
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup',
'type' => 'left',
'titre' => 'Ticket',
'mainmenu' => 'ticketsup',
'leftmenu' => 'ticketsup',
'url' => '/ticketsup/index.php',
'langs' => 'ticketsup@ticketsup',
'position' => 101,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->read',
'target' => '',
'user' => 2);
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup,fk_leftmenu=ticketsup',
'type' => 'left',
'titre' => 'NewTicket',
'mainmenu' => 'ticketsup',
'url' => '/ticketsup/new.php?action=create_ticket',
'langs' => 'ticketsup@ticketsup',
'position' => 102,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->create',
'target' => '',
'user' => 2);
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup,fk_leftmenu=ticketsup',
'type' => 'left',
'titre' => 'List',
'mainmenu' => 'ticketsup',
'leftmenu' => 'ticketsuplist',
'url' => '/ticketsup/list.php',
'langs' => 'ticketsup@ticketsup',
'position' => 103,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->read',
'target' => '',
'user' => 2);
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup,fk_leftmenu=ticketsuplist',
'type' => 'left',
'titre' => 'MenuListNonClosed',
'mainmenu' => 'ticketsup',
'leftmenu' => 'ticketsuplist',
'url' => '/ticketsup/list.php?search_fk_status=non_closed',
'langs' => 'ticketsup@ticketsup',
'position' => 104,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->read',
'target' => '',
'user' => 2);
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup,fk_leftmenu=ticketsup',
'type' => 'left',
'titre' => 'MenuTicketsupMyAssign',
'mainmenu' => 'ticketsup',
'leftmenu' => 'ticketsupmy',
'url' => '/ticketsup/list.php?mode=my_assign',
'langs' => 'ticketsup@ticketsup',
'position' => 105,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->read',
'target' => '',
'user' => 0);
$r++;
$this->menu[$r] = array('fk_menu' => 'fk_mainmenu=ticketsup,fk_leftmenu=ticketsupmy',
'type' => 'left',
'titre' => 'MenuTicketsupMyAssignNonClosed',
'mainmenu' => 'ticketsup',
'url' => '/ticketsup/list.php?mode=my_assign&search_fk_status=non_closed',
'langs' => 'ticketsup@ticketsup',
'position' => 106,
'enabled' => 1,
'perms' => '$user->rights->ticketsup->read',
'target' => '',
'user' => 0);
$r++;
}
/**
* Function called when module is enabled.
* The init function add constants, boxes, permissions and menus
* (defined in constructor) into Dolibarr database.
* It also creates data directories
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function init($options = '')
{
$sql = array(
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110120, 'ticketsup', 'internal', 'SUPPORTTEC', 'Utilisateur assigné au ticket', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110121, 'ticketsup', 'internal', 'CONTRIBUTOR', 'Intervenant', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110122, 'ticketsup', 'external', 'SUPPORTCLI', 'Contact client suivi incident', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110123, 'ticketsup', 'external', 'CONTRIBUTOR', 'Intervenant', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_action_trigger (rowid,code,label,description,elementtype,rang) values ('','TICKETMESSAGE_SENTBYMAIL','Envoi message de réponse par mail','Executed when a response is made on a ticket','ticketsup','');", "ignoreerror" => 1),
);
$result = $this->loadTables();
return $this->_init($sql, $options);
}
/**
* Function called when module is disabled.
* Remove from database constants, boxes and permissions from Dolibarr database.
* Data directories are not deleted
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function remove($options = '')
{
$sql = array();
return $this->_remove($sql, $options);
}
/**
* Create tables, keys and data required by module
* Files llx_table1.sql, llx_table1.key.sql llx_data.sql with create table, create keys
* and create data commands must be stored in directory /ticketsup/sql/
* This function is called by this->init
*
* @return int <=0 if KO, >0 if OK
*/
private function loadTables()
{
return $this->_load_tables('/ticketsup/sql/');
}
}

View File

@ -0,0 +1,120 @@
<?php
/* Copyright (C) 2010-2014 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
* or see http://www.gnu.org/
*/
/**
* \file htdocs/core/modules/project/modules_project.php
* \ingroup project
* \brief File that contain parent class for projects models
* and parent class for projects numbering models
*/
/**
* Classe mere des modeles de numerotation des references de projets
*/
abstract class ModeleNumRefTicketsup
{
public $error = '';
/**
* Return if a module can be used or not
*
* @return boolean true if module can be used
*/
public function isEnabled()
{
return true;
}
/**
* Renvoi la description par defaut du modele de numerotation
*
* @return string Texte descripif
*/
public function info()
{
global $langs;
$langs->load("ticketsup@ticketsup");
return $langs->trans("NoDescription");
}
/**
* Renvoi un exemple de numerotation
*
* @return string Example
*/
public function getExample()
{
global $langs;
$langs->load("ticketsup@ticketsup");
return $langs->trans("NoExample");
}
/**
* Test si les numeros deja en vigueur dans la base ne provoquent pas de
* de conflits qui empechera cette numerotation de fonctionner.
*
* @return boolean false si conflit, true si ok
*/
public function canBeActivated()
{
return true;
}
/**
* Renvoi prochaine valeur attribuee
*
* @param Societe $objsoc Object third party
* @param Project $project Object project
* @return string Valeur
*/
public function getNextValue($objsoc, $project)
{
global $langs;
return $langs->trans("NotAvailable");
}
/**
* Renvoi version du module numerotation
*
* @return string Valeur
*/
public function getVersion()
{
global $langs;
$langs->load("admin");
if ($this->version == 'development') {
return $langs->trans("VersionDevelopment");
}
if ($this->version == 'experimental') {
return $langs->trans("VersionExperimental");
}
if ($this->version == 'dolibarr') {
return DOL_VERSION;
}
if ($this->version) {
return $this->version;
}
return $langs->trans("NotAvailable");
}
}

View File

@ -0,0 +1,153 @@
<?php
/* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2010 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
* or see http://www.gnu.org/
*/
/**
* \file htdocs/core/modules/ticketsup/mod_ticketsup_simple.php
* \ingroup ticketsup
* \brief File with class to manage the numbering module Simple for ticketsup references
*/
dol_include_once('/ticketsup/core/modules/modules_ticketsup.php');
/**
* Class to manage the numbering module Simple for ticketsup references
*/
class mod_ticketsup_simple extends ModeleNumRefTicketsup
{
public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
public $prefix = 'TS';
public $error = '';
public $nom = "Simple";
public $name = "Simple";
/**
* Return description of numbering module
*
* @return string Text with description
*/
public function info()
{
global $langs;
return $langs->trans("SimpleNumRefModelDesc", $this->prefix);
}
/**
* Return an example of numbering module values
*
* @return string Example
*/
public function getExample()
{
return $this->prefix . "0501-0001";
}
/**
* Test si les numeros deja en vigueur dans la base ne provoquent pas de
* de conflits qui empechera cette numerotation de fonctionner.
*
* @return boolean false si conflit, true si ok
*/
public function canBeActivated()
{
global $conf, $langs, $db;
$coyymm = '';
$max = '';
$posindice = 8;
$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM " . $posindice . ") AS SIGNED)) as max";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup";
$sql .= " WHERE ref LIKE '" . $this->prefix . "____-%'";
$sql .= " AND entity = " . $conf->entity;
$resql = $db->query($sql);
if ($resql) {
$row = $db->fetch_row($resql);
if ($row) {
$coyymm = substr($row[0], 0, 6);
$max = $row[0];
}
}
if (!$coyymm || preg_match('/' . $this->prefix . '[0-9][0-9][0-9][0-9]/i', $coyymm)) {
return true;
} else {
$langs->load("errors");
$this->error = $langs->trans('ErrorNumRefModel', $max);
return false;
}
}
/**
* Return next value
*
* @param Societe $objsoc Object third party
* @param Project $ticketsup Object ticketsup
* @return string Value if OK, 0 if KO
*/
public function getNextValue($objsoc, $ticketsup)
{
global $db, $conf;
// D'abord on recupere la valeur max
$posindice = 8;
$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM " . $posindice . ") AS SIGNED)) as max";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup";
$sql .= " WHERE ref like '" . $this->prefix . "____-%'";
$sql .= " AND entity = " . $conf->entity;
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
if ($obj) {
$max = intval($obj->max);
} else {
$max = 0;
}
} else {
dol_syslog("mod_ticketsup_simple::getNextValue", LOG_DEBUG);
return -1;
}
$date = empty($ticketsup->datec) ? dol_now() : $ticketsup->datec;
//$yymm = strftime("%y%m",time());
$yymm = strftime("%y%m", $date);
if ($max >= (pow(10, 4) - 1)) {
$num = $max + 1;
} // If counter > 9999, we do not format on 4 chars, we take number as it is
else {
$num = sprintf("%04s", $max + 1);
}
dol_syslog("mod_ticketsup_simple::getNextValue return " . $this->prefix . $yymm . "-" . $num);
return $this->prefix . $yymm . "-" . $num;
}
/**
* Return next reference not yet used as a reference
*
* @param Societe $objsoc Object third party
* @param Project $ticketsup Object ticketsup
* @return string Next not used reference
*/
public function ticketsup_get_num($objsoc = 0, $ticketsup = '')
{
return $this->getNextValue($objsoc, $ticketsup);
}
}

View File

@ -0,0 +1,136 @@
<?php
/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
*
* 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 <http://www.gnu.org/licenses/>.
* or see http://www.gnu.org/
*/
/**
* \file ticketsup/core/modules/ticketsup/mod_ticketsup_universal.php
* \ingroup ticketsup
* \brief Fichier contenant la classe du modele de numerotation de reference de projet Universal
*/
dol_include_once('/ticketsup/core/modules/modules_ticketsup.php');
/**
* Classe du modele de numerotation de reference de projet Universal
*/
class mod_ticketsup_universal extends ModeleNumRefTicketsup
{
public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
public $error = '';
public $nom = 'Universal';
public $name = 'Universal';
/**
* Renvoi la description du modele de numerotation
*
* @return string Texte descripif
*/
public function info()
{
global $conf, $langs;
$langs->load("ticketsup@ticketsup");
$langs->load("admin");
$form = new Form($this->db);
$texte = $langs->trans('GenericNumRefModelDesc') . "<br>\n";
$texte .= '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
$texte .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
$texte .= '<input type="hidden" name="action" value="updateMask">';
$texte .= '<input type="hidden" name="maskconstticketsup" value="TICKETSUP_UNIVERSAL_MASK">';
$texte .= '<table class="nobordernopadding" width="100%">';
$tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Ticketsup"), $langs->transnoentities("Ticketsup"));
$tooltip .= $langs->trans("GenericMaskCodes2");
$tooltip .= $langs->trans("GenericMaskCodes3");
$tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Ticketsup"), $langs->transnoentities("Ticketsup"));
$tooltip .= $langs->trans("GenericMaskCodes5");
// Parametrage du prefix
$texte .= '<tr><td>' . $langs->trans("Mask") . ':</td>';
$texte .= '<td align="right">' . $form->textwithpicto('<input type="text" class="flat" size="24" name="maskticketsup" value="' . $conf->global->TICKETSUP_UNIVERSAL_MASK . '">', $tooltip, 1, 1) . '</td>';
$texte .= '<td align="left" rowspan="2">&nbsp; <input type="submit" class="button" value="' . $langs->trans("Modify") . '" name="Button"></td>';
$texte .= '</tr>';
$texte .= '</table>';
$texte .= '</form>';
return $texte;
}
/**
* Renvoi un exemple de numerotation
*
* @return string Example
*/
public function getExample()
{
global $conf, $langs, $mysoc;
$old_code_client = $mysoc->code_client;
$mysoc->code_client = 'CCCCCCCCCC';
$numExample = $this->getNextValue($mysoc, '');
$mysoc->code_client = $old_code_client;
if (!$numExample) {
$numExample = $langs->trans('NotConfigured');
}
return $numExample;
}
/**
* Return next value
*
* @param Societe $objsoc Object third party
* @param Project $ticketsup Object ticketsup
* @return string Value if OK, 0 if KO
*/
public function getNextValue($objsoc, $ticketsup)
{
global $db, $conf;
include_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
// On defini critere recherche compteur
$mask = $conf->global->TICKETSUP_UNIVERSAL_MASK;
if (!$mask) {
$this->error = 'NotConfigured';
return 0;
}
$date = empty($ticketsup->date_c) ? dol_now() : $ticketsup->datec;
$numFinal = get_next_value($db, $mask, 'ticketsup', 'ref', '', $objsoc->code_client, $date);
return $numFinal;
}
/**
* Return next reference not yet used as a reference
*
* @param Societe $objsoc Object third party
* @param Project $ticketsup Object ticketsup
* @return string Next not used reference
*/
public function ticketsup_get_num($objsoc = 0, $ticketsup = '')
{
return $this->getNextValue($objsoc, $ticketsup);
}
}

View File

@ -0,0 +1,308 @@
<?php
/*
* Copyright (C) 2014-2016 Jean-François Ferry <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/core/triggers/interface_50_modTicketsup_TicketEmail.class.php
* \ingroup core
* \brief Fichier
* \remarks Son propre fichier d'actions peut etre cree par recopie de celui-ci:
* - Le nom du fichier doit etre: interface_99_modMymodule_Mytrigger.class.php
* ou: interface_99_all_Mytrigger.class.php
* - Le fichier doit rester stocke dans core/triggers
* - Le nom de la classe doit etre InterfaceMytrigger
* - Le nom de la propriete name doit etre Mytrigger
*/
require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
/**
* Class of triggers for ticketsup module
*/
class InterfaceTicketEmail extends DolibarrTriggers
{
public $db;
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct($db)
{
$this->db = $db;
$this->name = preg_replace('/^Interface/i', '', get_class($this));
$this->family = "ticketsup";
$this->description = "Triggers of the module ticketsup";
$this->version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' or version
$this->picto = 'ticketsup@ticketsup';
}
/**
* Return name of trigger file
*
* @return string Name of trigger file
*/
public function getName()
{
return $this->name;
}
/**
* Return description of trigger file
*
* @return string Description of trigger file
*/
public function getDesc()
{
return $this->description;
}
/**
* Return version of trigger file
*
* @return string Version of trigger file
*/
public function getVersion()
{
global $langs;
$langs->load("admin");
if ($this->version == 'development') {
return $langs->trans("Development");
} elseif ($this->version == 'experimental') {
return $langs->trans("Experimental");
} elseif ($this->version == 'dolibarr') {
return DOL_VERSION;
} elseif ($this->version) {
return $this->version;
} else {
return $langs->trans("Unknown");
}
}
/**
* Function called when a Dolibarrr business event is done.
* All functions "run_trigger" are triggered if file is inside directory htdocs/core/triggers
*
* @param string $action Event action code
* @param Object $object Object
* @param User $user Object user
* @param Translate $langs Object langs
* @param conf $conf Object conf
* @return int <0 if KO, 0 if no triggered ran, >0 if OK
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
{
$ok = 0;
switch ($action) {
case 'TICKET_ASSIGNED':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
if ($object->fk_user_assign != $user->id) {
$userstat = new User($this->db);
$res = $userstat->fetch($object->fk_user_assign);
if ($res) {
// Send email to assigned user
$subject = '[' . $conf->global->MAIN_INFO_SOCIETE_NOM . '] ' . $langs->transnoentities('TicketAssignedToYou');
$message = '<p>' . $langs->transnoentities('TicketAssignedEmailBody', $object->track_id, dolGetFirstLastname($user->firstname, $user->lastname)) . "</p>";
$message .= '<ul><li>' . $langs->trans('Title') . ' : ' . $object->subject . '</li>';
$message .= '<li>' . $langs->trans('Type') . ' : ' . $object->type_label . '</li>';
$message .= '<li>' . $langs->trans('Category') . ' : ' . $object->category_label . '</li>';
$message .= '<li>' . $langs->trans('Severity') . ' : ' . $object->severity_label . '</li>';
// Extrafields
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message .= '<li>' . $langs->trans($key) . ' : ' . $value . '</li>';
}
}
$message .= '</ul>';
$message .= '<p>' . $langs->trans('Message') . ' : <br />' . $object->message . '</p>';
$message .= '<p><a href="' . dol_buildpath('/ticketsup/card.php', 2) . '?track_id=' . $object->track_id . '">' . $langs->trans('SeeThisTicketIntomanagementInterface') . '</a><br /></p>';
$sendto = $userstat->email;
$from = dolGetFirstLastname($user->firstname, $user->lastname) . '<' . $user->email . '>';
// Init to avoid errors
$filepath = array();
$filename = array();
$mimetype = array();
$message = dol_nl2br($message);
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1);
if ($mailfile->error) {
setEventMessage($mailfile->error, 'errors');
} else {
$result = $mailfile->sendfile();
}
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
}
$ok = 1;
}
}
break;
case 'TICKET_CREATE':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
// Init to avoid errors
$filepath = array();
$filename = array();
$mimetype = array();
$langs->load('ticketsup@ticketsup');
$object->fetch('', $object->track_id);
/* Send email to admin */
$sendto = $conf->global->TICKETS_NOTIFICATION_EMAIL_TO;
$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin');
$message_admin= $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id)."\n\n";
$message_admin.='<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message_admin.='<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message_admin.='<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
$message_admin.='<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
$message_admin.='<li>'.$langs->trans('From').' : '.( $object->email_from ? $object->email_from : ( $object->fk_user_create > 0 ? $langs->trans('Internal') : '') ).'</li>';
// Extrafields
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message_admin.='<li>'.$langs->trans($key).' : '.$value.'</li>';
}
}
$message_admin.='</ul>';
if ($object->fk_soc > 0) {
$object->fetch_thirdparty();
$message_admin.='<p>'.$langs->trans('Company'). ' : '.$object->thirdparty->name.'</p>';
}
$message_admin.='<p>'.$langs->trans('Message').' : <br />'.$object->message.'</p>';
$message_admin.='<p><a href="'.dol_buildpath('/ticketsup/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
$from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKETS_NOTIFICATION_EMAIL_FROM.'>';
$replyto = $from;
$message_admin = dol_nl2br($message_admin);
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
if ($mailfile->error) {
dol_syslog($mailfile->error, LOG_DEBUG);
} else {
$result=$mailfile->sendfile();
}
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
}
/* Send email to customer */
$sendto = '';
if (empty($user->socid) && empty($user->email)) {
$object->fetch_thirdparty();
$sendto = $object->thirdparty->email;
} else {
$sendto = $user->email;
}
if ($sendto && $object->notify_tiers_at_create) {
$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectCustomer');
$message_customer= $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id)."\n\n";
$message_customer.='<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message_customer.='<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message_customer.='<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
$message_customer.='<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
// Extrafields
if ($conf->global->TICKETS_EXTRAFIELDS_PUBLIC) {
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message_customer.='<li>'.$langs->trans($key).' : '.$value.'</li>';
}
}
}
$message_customer.='</ul>';
$message_customer.='<p>'.$langs->trans('Message').' : <br />'.$object->message.'</p>';
$url_public_ticket = ($conf->global->TICKETS_URL_PUBLIC_INTERFACE?$conf->global->TICKETS_URL_PUBLIC_INTERFACE.'/':dol_buildpath('/ticketsup/public/view.php', 2)).'?track_id='.$object->track_id;
$message_customer.='<p>' . $langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer') . ' : <a href="'.$url_public_ticket.'">'.$url_public_ticket.'</a></p>';
$message_customer.='<p>'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'</p>';
$from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKETS_NOTIFICATION_EMAIL_FROM.'>';
$replyto = $from;
// Init to avoid errors
$filepath = array();
$filename = array();
$mimetype = array();
$message_customer = dol_nl2br($message_customer);
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
if ($mailfile->error) {
dol_syslog($mailfile->error, LOG_DEBUG);
} else {
$result=$mailfile->sendfile();
}
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
}
}
$ok = 1;
break;
case 'TICKET_DELETE':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
break;
case 'TICKET_MODIFY':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
break;
case 'TICKET_MARK_READ':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
break;
case 'TICKET_CLOSED':
dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
break;
}
return $ok;
}
}

View File

@ -0,0 +1,9 @@
--
-- Contenu de la table llx_c_ticketsup_severity
--
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(1, 'LOW', '10', 'Bas', '', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(2, 'NORMAL', '20', 'Normal', '', 1, 1, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(3, 'LOWHIGH', '30', 'Important', '', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(4, 'HIGH', '40', 'Critique / bloquant', '', 1, 0, NULL);

View File

@ -0,0 +1,8 @@
--
-- Contenu de la table llx_c_ticketsup_type
--
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(1, 'COM', '10', 'Question commerciale', 1, 1, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(2, 'INCIDENT', '20', 'Demande d''assistance', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(3, 'PROJET', '30', 'Suivi projet', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(4, 'OTHER', '40', 'Autre', 1, 0, NULL);

View File

@ -0,0 +1,5 @@
INSERT INTO llx_c_type_contact (rowid, element, source, code, libelle, active, module) VALUES(110120, 'ticketsup', 'internal', 'SUPPORTTEC', 'Utilisateur contact support', 1, NULL);
INSERT INTO llx_c_type_contact (rowid, element, source, code, libelle, active, module) VALUES(110121, 'ticketsup', 'internal', 'CONTRIBUTOR', 'Intervenant', 1, NULL);
INSERT INTO llx_c_type_contact (rowid, element, source, code, libelle, active, module) VALUES(110122, 'ticketsup', 'external', 'SUPPORTCLI', 'Contact client suivi incident', 1, NULL);
INSERT INTO llx_c_type_contact (rowid, element, source, code, libelle, active, module) VALUES(110123, 'ticketsup', 'external', 'CONTRIBUTOR', 'Intervenant', 1, NULL);

View File

@ -0,0 +1,17 @@
--
-- Contenu de la table llx_c_ticketsup_type
--
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(1, 'COM', '10', 'Question commerciale', 1, 1, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(2, 'INCIDENT', '20', 'Demande d''assistance', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(3, 'PROJET', '30', 'Suivi projet', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_type (rowid, code, pos, label, active, use_default, description) VALUES(4, 'OTHER', '40', 'Autre', 1, 0, NULL);
--
-- Contenu de la table llx_c_ticketsup_severity
--
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(1, 'LOW', '10', 'Bas', '', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(2, 'NORMAL', '20', 'Normal', '', 1, 1, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(3, 'LOWHIGH', '30', 'Important', '', 1, 0, NULL);
INSERT INTO llx_c_ticketsup_severity (rowid, code, pos, label, color, active, use_default, description) VALUES(4, 'HIGH', '40', 'Critique / bloquant', '', 1, 0, NULL);

View File

@ -0,0 +1,18 @@
-- Copyright (C) 2018 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
ALTER TABLE llx_c_ticketsup_category ADD INDEX idx_code (code);

View File

@ -0,0 +1,27 @@
-- Copyright (C) 2013-2018 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
create table llx_c_ticketsup_category
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
code varchar(32) NOT NULL,
pos varchar(32) NOT NULL,
label varchar(128) NOT NULL,
active integer DEFAULT 1,
use_default integer DEFAULT 1,
description varchar(255)
)ENGINE=innodb;

View File

@ -0,0 +1,18 @@
-- Copyright (C) 2018 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
ALTER TABLE llx_c_ticketsup_severity ADD INDEX idx_code (code);

View File

@ -0,0 +1,28 @@
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
create table llx_c_ticketsup_severity
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
code varchar(32) NOT NULL,
pos varchar(32) NOT NULL,
label varchar(128) NOT NULL,
color varchar(10) NOT NULL,
active integer DEFAULT 1,
use_default integer DEFAULT 1,
description varchar(255)
)ENGINE=innodb;

View File

@ -0,0 +1,18 @@
-- Copyright (C) 2018 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
ALTER TABLE llx_c_ticketsup_type ADD INDEX idx_code (code);

View File

@ -0,0 +1,27 @@
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
create table llx_c_ticketsup_type
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
code varchar(32) NOT NULL,
pos varchar(32) NOT NULL,
label varchar(128) NOT NULL,
active integer DEFAULT 1,
use_default integer DEFAULT 1,
description varchar(255)
)ENGINE=innodb;

View File

@ -0,0 +1,17 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
ALTER TABLE llx_ticketsup ADD UNIQUE uk_matable_field(rowid, track_id);

View File

@ -0,0 +1,41 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
CREATE TABLE llx_ticketsup
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1,
ref varchar(128) NOT NULL,
track_id varchar(128) NOT NULL,
fk_soc integer DEFAULT 0,
fk_project integer DEFAULT 0,
origin_email varchar(128),
fk_user_create integer,
fk_user_assign integer,
subject varchar(255),
message text,
fk_statut integer,
resolution integer,
progress varchar(100),
timing varchar(20),
type_code varchar(32),
category_code varchar(32),
severity_code varchar(32),
datec datetime,
date_read datetime,
date_close datetime,
tms timestamp
)ENGINE=innodb;

View File

@ -0,0 +1,24 @@
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 2 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 <http://www.gnu.org/licenses/>.
--
--
create table llx_ticketsup_extrafields
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
tms timestamp,
fk_object integer NOT NULL, -- ticket id
import_key varchar(14) -- import key
)ENGINE=innodb;

View File

@ -0,0 +1,17 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
ALTER TABLE llx_ticketsup_logs ADD CONSTRAINT fk_ticketsup_logs_fk_track_id FOREIGN KEY (fk_track_id) REFERENCES llx_ticketsup (fk_track_id);

View File

@ -0,0 +1,25 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
CREATE TABLE llx_ticketsup_logs
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1,
fk_track_id varchar(128),
fk_user_create integer,
datec datetime,
message text
)ENGINE=innodb;

View File

@ -0,0 +1,17 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
ALTER TABLE llx_ticketsup_msg ADD CONSTRAINT fk_ticketsup_msg_fk_track_id FOREIGN KEY (fk_track_id) REFERENCES llx_ticketsup (track_id);

View File

@ -0,0 +1,26 @@
-- SQL definition for module ticketsup
-- Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
--
-- 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 <http://www.gnu.org/licenses/>.
CREATE TABLE llx_ticketsup_msg
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1,
fk_track_id varchar(128),
fk_user_action integer,
datec datetime,
message text,
private integer DEFAULT 0
)ENGINE=innodb;

View File

@ -0,0 +1,301 @@
# en_US lang file for module ticketsup
# Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
#
# 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 <http://www.gnu.org/licenses/>.
#
# Generic
#
Module110120Name = Tickets
Module110120Desc = Ticket system for incident management
Permission110121=See tickets
Permission110122=Modify tickets
Permission110123=Delete tickets
Permission110124=Manage tickets
Permission110125=See tickets of all thirdparties (not effective for external users, always be limited to the thirdparty they depend on)
TicketsupDictType=Tickets type
TicketsupDictCategory=Tickets categories
TicketsupDictSeverity=Severity classifications
TicketTypeShortBUGSOFT=Dysfonctionnement logiciel
TicketTypeShortBUGHARD=Dysfonctionnement matériel
TicketTypeShortCOM=Commercial question
TicketTypeShortINCIDENT=Request for assistance
TicketTypeShortPROJET=Project
TicketTypeShortOTHER=Other
TicketSeverityShortLOW=Low
TicketSeverityShortNORMAL=Normal
TicketSeverityShortLOWHIGH=Important
TicketSeverityShortHIGH=Critical
ErrorBadEmailAddress=Field '%s' incorrect
MenuTicketsupMyAssign=My tickets
MenuTicketsupMyAssignNonClosed=My tickets non closed
MenuListNonClosed=Non closed tickets
TypeContact_ticketsup_internal_CONTRIBUTOR=Contributor
TypeContact_ticketsup_internal_SUPPORTTEC=Assigned user
TypeContact_ticketsup_external_SUPPORTCLI=Customer contact / incident tracking
TypeContact_ticketsup_external_CONTRIBUTOR=External contributor
Notify_TICKETMESSAGE_SENTBYMAIL=Send ticket answer by email
# Status
NotRead=Not read
Read=Read
Answered=Answered
Assigned=Assigned
InProgress=In progress
Waiting=Waiting
Closed=Closed
Deleted=Deleted
# Dict
Type=Type
Category=Category
Severity=Severity
# Email templates
MailToSendTicketsupMessage = To send email from ticket message
#
# Admin page
#
TicketsupSetup = Ticket module setup
TicketSupSettings = Settings
TicketsupSetupPage =
TicketsupPublicAccess = A public interface requiring no identification is available at the following url
TicketsupSetupDictionaries = The type of application categories and severity level are configurable from dictionaries
TicketParamModule=Module variable setup
TicketParamMail=Email setup
TicketEmailNotificationFrom = Notification email from
TicketEmailNotificationFromHelp = Used into ticket message answer by example
TicketEmailNotificationTo = Notifications email to
TicketEmailNotificationToHelp = Send email notifications to this address.
TicketNewEmailBodyLabel=Text message sent after creating a ticket (public interface)
TicketNewEmailBodyHelp=The text specified here will be inserted into the email confirming the creation of a new ticket from the public interface. Information on the consultation of the ticket are automatically added.
TicketParamPublicInterface=Public interface setup
TicketsEmailMustExist=Require an existing email address to create a ticket
TicketsEmailMustExistHelp=In the public interface, the email address should already be filled in the database to create a new ticket.
PublicInterface=Public interface
TicketUrlPublicInterfaceLabelAdmin=Public interface URL
TicketUrlPublicInterfaceHelpAdmin=It is possible to define an alias to the web server and thus make available the public interface to another IP address.
TicketPublicInterfaceTextHomeLabelAdmin=Welcome text of the public interface
TicketPublicInterfaceTextHome=You can create a support ticket or view existing from its identifier tracking ticket.
TicketPublicInterfaceTextHomeHelpAdmin=The text defined here will appear on the home page of the public interface.
TicketPublicInterfaceTopicLabelAdmin=Interface title
TicketPublicInterfaceTopicHelp=This text will appear as the title of the public interface.
TicketPublicInterfaceTextHelpMessageLabelAdmin=Help text to the message entry
TicketPublicInterfaceTextHelpMessageHelpAdmin=This text will appear above the message input area of the user.
ExtraFieldsTicketSup=Extra attributes
TicketSupCkEditorEmailNotActivated=HTML editor is not activated. Please put FCKEDITOR_ENABLE_MAIL contant equal to 1
TicketsDisableEmail=Do not send ticket creation or message send emails
TicketsDisableEmailHelp=By default, emails are sent when new tickets or messages created. Enable this option to disable *all* email notifications
TicketsLogEnableEmail=Enable log by email
TicketsLogEnableEmailHelp=At each change, an email will be sent **to each contact** associated with the ticket.
TicketParams=Params
TicketsShowModuleLogo=Display the logo of the module in the public interface
TicketsShowModuleLogoHelp=Enable this option to hide the logo module in the pages of the public interface
TicketsShowCompanyLogo=Display the logo of the company in the public interface
TicketsShowCompanyLogoHelp=Enable this option to hide the logo of the main company in the pages of the public interface
TicketsEmailAlsoSendToMainAddress=Also send notification to main email address
TicketsEmailAlsoSendToMainAddressHelp=Enable this option to send an email to "Notification email from" address (see setup below)
TicketsShowExtrafieldsIntoPublicArea=Show Extras fields in the public interface
TicketsShowExtrafieldsIntoPublicAreaHelp=When this option is enabled, additional attributes defined on the tickets will be shown in the public interface of ticket creation.
TicketsLimitViewAssignedOnly=Restrict the display to tickets assigned to the current user (not effective for external users, always be limited to the thirdparty they depend on)
TicketsLimitViewAssignedOnlyHelp=Only tickets assigned to the current user will be visible. Does not apply to a user with tickets management rights.
TicketsActivatePublicInterface=Activate public interface
TicketsActivatePublicInterfaceHelp=Public interface allow any visitors to create tickets.
TicketsAutoAssignTicket=Automatically assign the user who created the ticket
TicketsAutoAssignTicketHelp=When creating a ticket, the user can be automatically assigned to the ticket.
TicketSupNumberingModules=Tickets numbering module
TicketNotNotifyTiersAtCreate=Do not notify the company to the creation
#
# About page
#
About = About
TicketSupAbout = About ticket module
TicketSupAboutModule = The development of this module has been initiated by the company Libr&thic.
TicketSupAboutModuleHelp=You can get help by using the contact form on the website <a href="http://librethic.io">librethic.io</a>
TicketSupAboutModuleImprove=Feel free to suggest improvements! Please visit <a href="https://code.librethic.io/Dolibarr/modules/ticketsup">the project page</a> on Doliforge website to report bugs and add tasks.
TicketSupAboutModuleThanks=Thanks to <a href="http://sayatnowa.com">nwa</a> who creates icons for this module./
#
# Index & list page
#
TicketsIndex=Ticket - home
TicketList=List of tickets
TicketAssignedToMeInfos=This page display ticket list which are assigned to current user
NoTicketsFound=No ticket found
TicketViewAllTickets=View all tickets
TicketViewNonClosedOnly=View only non closed tickets
TicketStatByStatus=Tickets par statut
#
# Ticket card
#
Ticketsup=Incident ticket
TicketCard=Ticket card
CreateTicket=Create new ticket
EditTicket=Edit ticket
TicketsManagement=Tickets Management
CreatedBy=Created by
NewTicket=New Ticket
SubjectAnswerToTicket=Ticket answer
TicketTypeRequest=Request type
TicketCategory=Category
SeeTicket=See ticket
TicketMarkedAsRead=Ticket has been marked as read
TicketReadOn=Read on
TicketCloseOn=Clotured on
UserAssignedTo=User assigned
MarkAsRead=Mark ticket as read
TicketMarkedAsReadButLogActionNotSaved=Ticket marked as closed but no action saved
TicketHistory=Ticket history
AssignUser=Assign to user
TicketAssigned=Ticket is now assigned
TicketChangeType=Change type
TicketChangeCategory=Change category
TicketChangeSeverity=Change severity
TicketAddMessage=Add a message
TicketEditProperties=Edit properties
AddMessage=Add a message
MessageSuccessfullyAdded=Ticket added
TicketMessageSuccessfullyAdded=Message successfully added
TicketMessagesList=Message list
NoMsgForThisTicket=No message for this ticket
Properties=Classification
LastNewTickets=Last %s tickets newest (not read)
TicketSeverity=Severity
ShowTicket=See ticket
RelatedTickets=Related tickets
TicketAddIntervention=Create intervention
CloseTicket=Close ticket
CloseATicket=Close a ticket
ConfirmCloseAticket=Confirm ticket closing
ConfirmDeleteTicket=Please confirm ticket deleting
TicketDeletedSuccess=Ticket deleted with success
TicketMarkedAsClosed=Ticket marked as closed
TicketMarkedAsClosedButLogActionNotSaved=Ticket marked as closed but no log saved !
TicketDurationAuto=Calculated duration
TicketDurationAutoInfos=Duration calculated automatically from intervention related
TicketUpdated=Ticket updated
SendMessageByEmail=Send message by email
TicketNewMessage=New message
ErrorMailRecipientIsEmptyForSendTicketMessage=Recipient is empty. No email send
TicketGoIntoContactTab=Please go into "Contacts" tab to select them
TicketMessageMailIntro=Introduction
TicketMessageMailIntroHelp=This text is added only at the beginning of the email and will not be saved.
TicketMessageMailIntroLabelAdmin=Introduction to the message when sending email
TicketMessageMailIntroText=<p> Hello </ p> A new response was sent on a ticket that you contact. Here is the message: </ p>
TicketMessageMailIntroHelpAdmin=This text will be inserted before the text of the response to a ticket.
TicketMessageMailSignature=Signature
TicketMessageMailSignatureHelp=This text is added only at the end of the email and will not be saved.
TicketMessageMailSignatureText=<p>Cordialement,</p><p>--</p>
TicketMessageMailSignatureLabelAdmin=Signature of response email
TicketMessageMailSignatureHelpAdmin=This text will be inserted after the response message.
TicketMessageHelp=Only this text will be saved in the message list on ticket card.
TicketMessageSubstitutionReplacedByGenericValues=Substitutions variables are replaced by generic values.
TicketTimeToRead=Time elapsed before ticket read
TicketContacts=Contacts ticket
TicketDocumentsLinked=Documents linked to ticket
ConfirmReOpenTicket=Confirm reopen this ticket ?
TicketMessageMailIntroAutoNewPublicMessage=A new message was posted on the ticket with the subject %s :
TicketAssignedToYou=Ticket assigned
TicketAssignedEmailBody=You have been assigned the ticket #%s by %s
MarkMessageAsPrivate=Mark message as private
TicketMessagePrivateHelp=This message will not display to external users
TicketEmailOriginIssuer=Issuer at origin of the tickets
InitialMessage=Initial Message
LinkToAContract=Link to a contract
TicketSupPleaseSelectAContract=Select a contract
UnableToCreateInterIfNoSocid=Can not create a response file without defining a thirdparty
TicketMailExchanges=Mail exchanges
TicketInitialMessageModified=Initial message modified
TicketMessageSuccesfullyUpdated=Message successfully updated
TicketChangeStatus=Change status
TicketConfirmChangeStatus=Confirm the status change : %s ?
TicketLogStatusChanged=Status changed : %s to %s
TicketNotNotifyTiersAtCreate=Not notify company at create
#
# Logs
#
TicketLogMesgReadBy=Ticket read by %s
NoLogForThisTicket=No log for this ticket yet
TicketLogAssignedTo=Ticket assigned to %s
TicketAssignedButLogActionNotSaved=Ticket assigned but no log saved !
TicketLogPropertyChanged=Change classification : from %s to %s
TicketLogClosedBy=Ticket closed by %s
TicketLogProgressSetTo=Progress change to %s percent
TicketLogReopen=Ticket re-opened
#
# Public pages
#
TicketSystem=Ticket system
ShowListTicketWithTrackId=Display ticket list from track ID
ShowTicketWithTrackId=Display ticket from track ID
TicketPublicDesc=You can create a support ticket or check from an existing ID.
YourTicketSuccessfullySaved=Ticket has been successfully saved!
MesgInfosPublicTicketCreatedWithTrackId=A new ticket has been created with ID %s.
PleaseRememberThisId=Please keep the tracking number that we might ask you later.
TicketNewEmailSubject=Ticket creation confirmation
TicketNewEmailSubjectCustomer=New support ticket
TicketNewEmailBody=This is an automatic email to confirm you have registered a new ticket.
TicketNewEmailBodyCustomer=This is an automatic email to confirm a new ticket has just been created into your account.
TicketNewEmailBodyInfosTicket=Information for monitoring the ticket
TicketNewEmailBodyInfosTrackId=Ticket tracking number : %s
TicketNewEmailBodyInfosTrackUrl=You can view the progress of the ticket by clicking the link above.
TicketNewEmailBodyInfosTrackUrlCustomer=You can view the progress of the ticket in the specific interface by clicking the following link
TicketEmailPleaseDoNotReplyToThisEmail=Please do not reply directly to this email! Use the link to reply into the interface.
TicketPublicInfoCreateTicket=This form allows you to record a trouble ticket in our management system.
TicketPublicPleaseBeAccuratelyDescribe=Please accurately describe the problem. Provide the most information possible to allow us to correctly identify your request.
TicketPublicMsgViewLogIn=Please enter ticket tracking ID
TicketTrackId=Tracking ID
OneOfTicketTrackId=One of yours tracking ID
ErrorTicketNotFound=Ticket with tracking ID %s not found !
Subject=Subject
ViewTicket=View ticket
ViewMyTicketList=View my ticket list
ErrorEmailMustExistToCreateTicket=Error : email address not found in our database
TicketNewEmailSubjectAdmin=New ticket created
TicketNewEmailBodyAdmin=<p>Ticket has just been created with ID #%s, see informations :</p>
SeeThisTicketIntomanagementInterface=See ticket in management interface
TicketPublicInterfaceForbidden=Access for this area : forbidden
# notifications
TicketNotificationEmailSubject=Ticket %s updated
TicketNotificationEmailBody=This is an automatic message to notify you that ticket %s has just been updated
TicketNotificationRecipient=Notification recipient
TicketNotificationLogMessage=Log message
TicketNotificationEmailBodyInfosTrackUrlinternal=View ticket into interface
TicketNotificationNumberEmailSent=Notification email sent : %s
#
# Boxes
#
BoxLastTicketsup=Last tickets
BoxLastTicketsupDescription=Last %s tickets saved
BoxLastTicketsupContent=
BoxLastTicketsupNoRecordedTickets=No recent unread tickets
BoxLastModifiedTicketsup=Last modified tickets
BoxLastModifiedTicketsupDescription=Last %s tickets modified
BoxLastModifiedTicketsupContent=
BoxLastModifiedTicketsupNoRecordedTickets=No recent modified tickets

View File

@ -0,0 +1,384 @@
<?php
/*
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* Display public form to add new ticket
*
* @package ticketsup
*/
if (!defined('NOREQUIREUSER')) {
define('NOREQUIREUSER', '1');
}
//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
if (!defined('NOTOKENRENEWAL')) {
define('NOTOKENRENEWAL', '1');
}
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
// If there is no menu to show
if (!defined('NOREQUIREHTML')) {
define('NOREQUIREHTML', '1');
}
// If we don't need to load the html.form.class.php
//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
define("NOLOGIN", 1); // This means this output page does not require to be logged.
define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
// Change this following line to use the correct relative path (../, ../../, etc)
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = @include "../main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include "../../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
dol_include_once('/ticketsup/class/ticketsup.class.php');
dol_include_once('/ticketsup/class/html.formticketsup.class.php');
dol_include_once('/ticketsup/lib/ticketsup.lib.php');
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("mails");
$langs->load("ticketsup@ticketsup");
// Get parameters
$id = GETPOST('id', 'int');
$msg_id = GETPOST('msg_id', 'int');
$action = GETPOST('action', 'alpha');
$object = new Ticketsup($db);
/*
* Add file in email form
*/
if (GETPOST('addfile') && !GETPOST('add_ticket')) {
////$res = $object->fetch('',GETPOST('track_id'));
////if($res > 0)
////{
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
// Set tmp directory TODO Use a dedicated directory for temp mails files
$vardir = $conf->ticketsup->dir_output;
$upload_dir_tmp = $vardir . '/temp';
if (!dol_is_dir($upload_dir_tmp)) {
dol_mkdir($upload_dir_tmp);
}
dol_add_file_process($upload_dir_tmp, 0, 0, 'addedfile');
$action = 'create_ticket';
////}
}
/*
* Remove file in email form
*/
if (GETPOST('removedfile') && !GETPOST('add_ticket')) {
////$res = $object->fetch('',GETPOST('track_id'));
////if($res > 0)
////{
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
// Set tmp directory
$vardir = $conf->ticketsup->dir_output . '/';
$upload_dir_tmp = $vardir . '/temp';
// TODO Delete only files that was uploaded from email form
dol_remove_file_process($_POST['removedfile'], 0);
$action = 'create_ticket';
////}
}
if ($action == 'create_ticket' && GETPOST('add_ticket')) {
$error = 0;
$origin_email = GETPOST('email', 'alpha');
if (empty($origin_email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Email")));
$action = '';
} else {
// Search company saved with email
$searched_companies = $object->searchSocidByEmail($origin_email, '0');
// Chercher un contact existant avec cette adresse email
// Le premier contact trouvé est utilisé pour déterminer le contact suivi
$contacts = $object->searchContactByEmail($origin_email);
// Option to require email exists to create ticket
if (!empty($conf->global->TICKETS_EMAIL_MUST_EXISTS) && !$contacts[0]->socid) {
$error++;
array_push($object->errors, $langs->trans("ErrorEmailMustExistToCreateTicket"));
$action = '';
}
}
if (!GETPOST("subject")) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")));
$action = '';
} elseif (!GETPOST("message")) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("message")));
$action = '';
}
// Check email address
if (!isValidEmail($origin_email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorBadEmailAddress", $langs->transnoentities("email")));
$action = '';
}
if (!$error) {
$object->db->begin();
$object->track_id = generate_random_id(16);
$object->subject = GETPOST("subject");
$object->message = GETPOST("message");
$object->origin_email = $origin_email;
$object->type_code = GETPOST("type_code");
$object->category_code = GETPOST("category_code");
$object->severity_code = GETPOST("severity_code");
if (is_array($searched_companies)) {
$object->fk_soc = $searched_companies[0]->id;
}
if (is_array($contacts) and count($contacts) > 0) {
$object->fk_soc = $contacts[0]->socid;
$usertoassign = $contacts[0]->id;
}
if (!empty($conf->global->TICKETS_EXTRAFIELDS_PUBLIC) && $conf->global->TICKETS_EXTRAFIELDS_PUBLIC == "1") {
$extrafields = new ExtraFields($db);
$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
}
// Generate new ref
$object->ref = $object->getDefaultRef();
if (!is_object($user)) {
$user = new User($db);
}
$id = $object->create($user, 1); // Disable trigger for email (send by this page)
if ($id <= 0) {
$error++;
$errors = ($object->error ? array($object->error) : $object->errors);
array_push($object->errors, $object->error ? array($object->error) : $object->errors);
$action = 'create_ticket';
}
if (!$error && $id > 0) {
if ($usertoassign > 0) {
$object->add_contact($usertoassign, "SUPPORTCLI", 'external', $notrigger = 0);
}
$object->db->commit();
$res = $object->fetch($id);
if ($res) {
// Create form object
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
$formmail = new FormMail($db);
// Init to avoid errors
$filepath = array();
$filename = array();
$mimetype = array();
$attachedfiles = $formmail->get_attached_files();
$filepath = $attachedfiles['paths'];
$filename = $attachedfiles['names'];
$mimetype = $attachedfiles['mimes'];
// Send email to customer
$subject = '[' . $conf->global->MAIN_INFO_SOCIETE_NOM . '] ' . $langs->transnoentities('TicketNewEmailSubject');
$message .= ($conf->global->TICKETS_MESSAGE_MAIL_NEW ? $conf->global->TICKETS_MESSAGE_MAIL_NEW : $langs->transnoentities('TicketNewEmailBody')) . "\n\n";
$message .= $langs->transnoentities('TicketNewEmailBodyInfosTicket') . "\n";
$url_public_ticket = ($conf->global->TICKETS_URL_PUBLIC_INTERFACE ? $conf->global->TICKETS_URL_PUBLIC_INTERFACE . '/' : dol_buildpath('/ticketsup/public/view.php', 2)) . '?track_id=' . $object->track_id;
$infos_new_ticket = $langs->transnoentities('TicketNewEmailBodyInfosTrackId', '<a href="' . $url_public_ticket . '">' . $object->track_id . '</a>') . "\n";
$infos_new_ticket .= $langs->transnoentities('TicketNewEmailBodyInfosTrackUrl') . "\n\n";
$message .= dol_nl2br($infos_new_ticket);
$message .= $conf->global->TICKETS_MESSAGE_MAIL_SIGNATURE ? $conf->global->TICKETS_MESSAGE_MAIL_SIGNATURE : $langs->transnoentities('TicketMessageMailSignatureText');
$sendto = GETPOST('email');
$from = $conf->global->MAIN_INFO_SOCIETE_NOM . '<' . $conf->global->TICKETS_NOTIFICATION_EMAIL_FROM . '>';
$replyto = $from;
$message = dol_nl2br($message);
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
if ($mailfile->error) {
setEventMessage($mailfile->error, 'errors');
} else {
$result = $mailfile->sendfile();
}
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
}
/* Send email to admin */
$sendto = $conf->global->TICKETS_NOTIFICATION_EMAIL_TO;
$subject = '[' . $conf->global->MAIN_INFO_SOCIETE_NOM . '] ' . $langs->transnoentities('TicketNewEmailSubjectAdmin');
$message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id) . "\n\n";
$message_admin .= '<ul><li>' . $langs->trans('Title') . ' : ' . $object->subject . '</li>';
$message_admin .= '<li>' . $langs->trans('Type') . ' : ' . $object->type_label . '</li>';
$message_admin .= '<li>' . $langs->trans('Category') . ' : ' . $object->category_label . '</li>';
$message_admin .= '<li>' . $langs->trans('Severity') . ' : ' . $object->severity_label . '</li>';
$message_admin .= '<li>' . $langs->trans('From') . ' : ' . $object->origin_email . '</li>';
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message_admin .= '<li>' . $langs->trans($key) . ' : ' . $value . '</li>';
}
}
$message_admin .= '</ul>';
$message_admin .= '<p>' . $langs->trans('Message') . ' : <br />' . $object->message . '</p>';
$message_admin .= '<p><a href="' . dol_buildpath('/ticketsup/card.php', 2) . '?track_id=' . $object->track_id . '">' . $langs->trans('SeeThisTicketIntomanagementInterface') . '</a></p>';
$from = $conf->global->MAIN_INFO_SOCIETE_NOM . '<' . $conf->global->TICKETS_NOTIFICATION_EMAIL_FROM . '>';
$replyto = $from;
$message_admin = dol_nl2br($message_admin);
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
if ($mailfile->error) {
setEventMessage($mailfile->error, 'errors');
} else {
$result = $mailfile->sendfile();
}
if (!empty($conf->global->TICKETS_DISABLE_MAIL_AUTOCOPY_TO)) {
$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
}
// Copy files into ticket directory
$destdir = $conf->ticketsup->dir_output . '/' . $object->track_id;
if (!dol_is_dir($destdir)) {
dol_mkdir($destdir);
}
foreach ($filename as $i => $val) {
dol_move($filepath[$i], $destdir . '/' . $filename[$i], 0, 1);
$formmail->remove_attached_files($i);
}
}
setEventMessage($langs->trans('YourTicketSuccessfullySaved'));
$action = "infos_success";
} else {
$object->db->rollback();
setEventMessage($object->errors, 'errors');
$action = 'create_ticket';
}
} else {
setEventMessage($object->errors, 'errors');
}
}
/***************************************************
* PAGE
*
****************************************************/
$arrayofjs = array();
$arrayofcss = array('/opensurvey/css/style.css', '/ticketsup/css/styles.css', '/ticketsup/css/bg.css.php');
llxHeaderTicket($langs->trans("CreateTicket"), "", 0, 0, $arrayofjs, $arrayofcss);
$form = new Form($db);
$formticket = new FormTicketsup($db);
if (!$conf->global->TICKETS_ENABLE_PUBLIC_INTERFACE) {
print '<div class="error">' . $langs->trans('TicketPublicInterfaceForbidden') . '</div>';
$db->close();
exit();
}
print '<div style="width:60%; margin: 0 auto;">';
if ($action != "infos_success") {
$formticket->withfromsocid = isset($socid) ? $socid : $user->societe_id;
$formticket->withtitletopic = 1;
$formticket->withcompany = 0;
$formticket->withusercreate = 1;
$formticket->fk_user_create = 0;
$formticket->withemail = 1;
$formticket->ispublic = 1;
$formticket->withfile = 2;
if (!empty($conf->global->TICKETS_EXTRAFIELDS_PUBLIC)) {
$formticket->withextrafields = $conf->global->TICKETS_EXTRAFIELDS_PUBLIC;
}
$formticket->action = 'create_ticket';
$formticket->param = array('returnurl' => $_SERVER['PHP_SELF']);
if (empty($defaultref)) {
$defaultref = '';
}
print load_fiche_titre($langs->trans('NewTicket'), '', 'ticketsup-32@ticketsup', 0);
print '<div class="info">' . $langs->trans('TicketPublicInfoCreateTicket') . '</div>';
$formticket->showForm();
} else {
print '<div class="ok">' . $langs->trans('MesgInfosPublicTicketCreatedWithTrackId', '<strong>' . $object->track_id . '</strong>');
print '<br />';
print $langs->trans('PleaseRememberThisId');
}
print '</div>';
/***************************************************
* LINKED OBJECT BLOCK
*
* Put here code to view linked object
****************************************************/
//$somethingshown=$object->showLinkedObjectBlock();
// End of page
$db->close();
llxFooter('');

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,107 @@
<?php
/* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/public/index.php
* \ingroup ticketsup
* \brief Public file to add and manage ticket
*/
//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
if (!defined('NOCSRFCHECK')) {
define('NOCSRFCHECK', '1');
}
// Do not check anti CSRF attack test
//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
// If there is no need to load and show top and left menu
//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
if (!defined("NOLOGIN")) {
define("NOLOGIN", '1');
}
// If this page is public (can be called outside logged session)
// Change this following line to use the correct relative path (../, ../../, etc)
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = @include '../main.inc.php';
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include '../../main.inc.php';
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include '../../../main.inc.php';
}
if (!$res) {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT . '/core/lib/security.lib.php';
// Change this following line to use the correct relative path from htdocs
dol_include_once('/ticketsup/class/ticketsup.class.php');
dol_include_once('/ticketsup/class/html.formticketsup.class.php');
dol_include_once('/ticketsup/lib/ticketsup.lib.php');
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
$langs->load("errors");
// Get parameters
$track_id = GETPOST('track_id', 'alpha');
$action = GETPOST('action', 'alpha');
/***************************************************
* VIEW
*
****************************************************/
$form = new Form($db);
$formticket = new FormTicketsup($db);
$arrayofjs = array();
$arrayofcss = array('/ticketsup/css/styles.css', '/ticketsup/css/bg.css.php');
llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss);
if (!$conf->global->TICKETS_ENABLE_PUBLIC_INTERFACE) {
print '<div class="error">' . $langs->trans('TicketPublicInterfaceForbidden') . '</div>';
} else {
print '<div style="margin: 0 auto; width:60%">';
print '<p style="text-align: center">' . ($conf->global->TICKETS_PUBLIC_TEXT_HOME ? $conf->global->TICKETS_PUBLIC_TEXT_HOME : $langs->trans("TicketPublicDesc")) . '</p>';
print '<div class="corps">';
print '<div class="index_create"><a href="create_ticket.php" class="button orange bigrounded"><strong>&nbsp;' . dol_escape_htmltag($langs->trans("CreateTicket")) . '</strong></a></div>';
print '<div class="index_display"><a href="list.php" class="button blue bigrounded"><strong>&nbsp;' . dol_escape_htmltag($langs->trans("ShowListTicketWithTrackId")) . '</strong></a></div>';
print '<div class="index_display"><a href="view.php" class="button blue bigrounded"><strong>&nbsp;' . dol_escape_htmltag($langs->trans("ShowTicketWithTrackId")) . '</strong></a></div>';
print '<div style="clear:both;"></div>';
print '</div>';
print '</div>';
}
// End of page
llxFooter();
$db->close();

View File

@ -0,0 +1,703 @@
<?php
/* Copyright (C) - 2013-2016 Jean-François FERRY <jfefe@aternatik.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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/public/index.php
* \ingroup ticketsup
* \brief Public file to add and manage ticket
*/
if (!defined('NOCSRFCHECK')) {
define('NOCSRFCHECK', '1');
}
// Do not check anti CSRF attack test
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
// If there is no need to load and show top and left menu
if (!defined("NOLOGIN")) {
define("NOLOGIN", '1');
}
// If this page is public (can be called outside logged session)
// Change this following line to use the correct relative path (../, ../../, etc)
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = @include '../main.inc.php';
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include '../../main.inc.php';
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include '../../../main.inc.php';
}
if (!$res) {
die("Include of main fails");
}
// Change this following line to use the correct relative path from htdocs
dol_include_once('/ticketsup/class/actions_ticketsup.class.php');
dol_include_once('/ticketsup/class/html.formticketsup.class.php');
dol_include_once('/ticketsup/lib/ticketsup.lib.php');
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
// Get parameters
$track_id = GETPOST('track_id', 'alpha');
$action = GETPOST('action', 'alpha', 3);
$email = GETPOST('email', 'alpha');
if (GETPOST('btn_view_ticket_list')) {
unset($_SESSION['track_id_customer']);
unset($_SESSION['email_customer']);
}
if (isset($_SESSION['track_id_customer'])) {
$track_id = $_SESSION['track_id_customer'];
}
if (isset($_SESSION['email_customer'])) {
$email = $_SESSION['email_customer'];
}
$object = new ActionsTicketsup($db);
if ($action == "view_ticketlist") {
$error = 0;
$display_ticket_list = false;
if (!strlen($track_id)) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketTrackId")));
$action = '';
}
if (!strlen($email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Email")));
$action = '';
} else {
if (!isValidEmail($email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorEmailInvalid"));
$action = '';
}
}
if (!$error) {
$ret = $object->fetch('', $track_id);
if ($ret && $object->dao->id > 0) {
// vérifie si l'adresse email est bien dans les contacts du ticket
$contacts = $object->dao->liste_contact(-1, 'external');
foreach ($contacts as $contact) {
if ($contact['email'] == $email) {
$display_ticket_list = true;
$_SESSION['email_customer'] = $email;
$_SESSION['track_id_customer'] = $track_id;
break;
} else {
$display_ticket_list = false;
}
}
if ($object->dao->fk_soc > 0) {
$object->dao->fetch_thirdparty();
}
if ($email == $object->dao->origin_email || $email == $object->dao->thirdparty->email) {
$display_ticket_list = true;
$_SESSION['email_customer'] = $email;
$_SESSION['track_id_customer'] = $track_id;
}
} else {
$error++;
array_push($object->errors, $langs->trans("ErrorTicketNotFound", $track_id));
$action = '';
}
}
if ($error) {
setEventMessage($object->errors, 'errors');
$action = '';
}
}
$object->doActions($action);
/***************************************************
* VIEW
*
****************************************************/
$form = new Form($db);
$user_assign = new User($db);
$user_create = new User($db);
$formticket = new FormTicketsup($db);
$arrayofjs = array();
$arrayofcss = array('/ticketsup/css/styles.css', '/ticketsup/css/bg.css.php');
llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss);
if (!$conf->global->TICKETS_ENABLE_PUBLIC_INTERFACE) {
print '<div class="error">' . $langs->trans('TicketPublicInterfaceForbidden') . '</div>';
$db->close();
exit();
}
print '<div style="margin: 0 auto; width:60%">';
if ($action == "view_ticketlist") {
if ($display_ticket_list) {
// Filters
$search_fk_status = GETPOST("search_fk_status", 'alpha');
$search_subject = GETPOST("search_subject");
$search_type = GETPOST("search_type", 'alpha');
$search_category = GETPOST("search_category", 'alpha');
$search_severity = GETPOST("search_severity", 'alpha');
$search_fk_user_create = GETPOST("search_fk_user_create", 'int');
$search_fk_user_assign = GETPOST("search_fk_user_assign", 'int');
// Store current page url
$url_page_current = dol_buildpath('/ticketsup/public/list.php', 1);
// Do we click on purge search criteria ?
if (GETPOST("button_removefilter_x")) {
$search_fk_status = '';
$search_subject = '';
$search_type = '';
$search_category = '';
$search_severity = '';
$search_fk_user_create = '';
$search_fk_user_assign = '';
}
// fetch optionals attributes and labels
$extrafields = new ExtraFields($db);
$extralabels = $extrafields->fetch_name_optionals_label('ticketsup');
$search_array_options = $extrafields->getOptionalsFromPost($extralabels, '', 'search_');
$filter = array();
$param = '';
// Definition of fields for list
$arrayfields = array(
't.datec' => array('label' => $langs->trans("Date"), 'checked' => 1),
't.date_read' => array('label' => $langs->trans("TicketReadOn"), 'checked' => 0),
't.date_close' => array('label' => $langs->trans("TicketCloseOn"), 'checked' => 0),
't.ref' => array('label' => $langs->trans("Ref"), 'checked' => 1),
't.fk_statut' => array('label' => $langs->trans("Statut"), 'checked' => 1),
't.subject' => array('label' => $langs->trans("Subject"), 'checked' => 1),
'type.code' => array('label' => $langs->trans("Type"), 'checked' => 1),
'category.code' => array('label' => $langs->trans("Category"), 'checked' => 1),
'severity.code' => array('label' => $langs->trans("Severity"), 'checked' => 1),
't.progress' => array('label' => $langs->trans("Progression"), 'checked' => 0),
//'t.fk_contract' => array('label' => $langs->trans("Contract"), 'checked' => 0),
't.fk_user_create' => array('label' => $langs->trans("Author"), 'checked' => 1),
't.fk_user_assign' => array('label' => $langs->trans("AuthorAssign"), 'checked' => 0),
//'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))),
//'t.datec' => array('label' => $langs->trans("DateCreation"), 'checked' => 0, 'position' => 500),
//'t.tms' => array('label' => $langs->trans("DateModificationShort"), 'checked' => 0, 'position' => 2)
//'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
);
// Extra fields
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) {
foreach ($extrafields->attribute_label as $key => $val) {
if ($extrafields->attribute_type[$key] != 'separate') {
$arrayfields["ef." . $key] = array('label' => $extrafields->attribute_label[$key], 'checked' => $extrafields->attribute_list[$key], 'position' => $extrafields->attribute_pos[$key], 'enabled' => $extrafields->attribute_perms[$key]);
}
}
}
if (!empty($search_subject)) {
$filter['t.subject'] = $search_subject;
$param .= '&search_subject=' . $search_subject;
}
if (!empty($search_type)) {
$filter['t.type_code'] = $search_type;
$param .= '&search_type=' . $search_type;
}
if (!empty($search_category)) {
$filter['t.category_code'] = $search_category;
$param .= '&search_category=' . $search_category;
}
if (!empty($search_severity)) {
$filter['t.severity_code'] = $search_severity;
$param .= '&search_severity=' . $search_severity;
}
if (!empty($search_fk_user_assign)) {
// -1 value = all so no filter
if ($search_fk_user_assign > 0) {
$filter['t.fk_user_assign'] = $search_fk_user_assign;
$param .= '&search_fk_user_assign=' . $search_fk_user_assign;
}
}
if (!empty($search_fk_user_create)) {
// -1 value = all so no filter
if ($search_fk_user_create > 0) {
$filter['t.fk_user_create'] = $search_fk_user_create;
$param .= '&search_fk_user_create=' . $search_fk_user_create;
}
}
if ((isset($search_fk_status) && $search_fk_status != '') && $search_fk_status != '-1' && $search_fk_status != 'non_closed') {
$filter['t.fk_statut'] = $search_fk_status;
$param .= '&search_fk_status=' . $search_fk_status;
}
if (isset($search_fk_status) && $search_fk_status == 'non_closed') {
$filter['t.fk_statut'] = array(0, 1, 3, 4, 5, 6);
$param .= '&search_fk_status=non_closed';
}
require DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
if (!$sortfield) {
$sortfield = 't.datec';
}
if (!$sortorder) {
$sortorder = 'DESC';
}
$limit = $conf->liste_limit;
$page = GETPOST("page", 'int');
if ($page == -1) {
$page = 0;
}
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
// Request SQL
$sql = "SELECT";
$sql .= " t.rowid,";
$sql .= " t.ref,";
$sql .= " t.track_id,";
$sql .= " t.fk_soc,";
$sql .= " t.fk_project,";
$sql .= " t.origin_email,";
$sql .= " t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
$sql .= " t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
$sql .= " t.subject,";
$sql .= " t.message,";
$sql .= " t.fk_statut,";
$sql .= " t.resolution,";
$sql .= " t.progress,";
$sql .= " t.timing,";
$sql .= " t.type_code,";
$sql .= " t.category_code,";
$sql .= " t.severity_code,";
$sql .= " t.datec,";
$sql .= " t.date_read,";
$sql .= " t.date_close,";
$sql .= " t.tms";
$sql .= ", type.label as type_label, category.label as category_label, severity.label as severity_label";
// Add fields for extrafields
foreach ($extrafields->attribute_list as $key => $val) {
$sql .= ($extrafields->attribute_type[$key] != 'separate' ? ",ef." . $key . ' as options_' . $key : '');
}
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup as t";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_type as type ON type.code=t.type_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_category as category ON category.code=t.category_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_severity as severity ON severity.code=t.severity_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid=t.fk_soc";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as uc ON uc.rowid=t.fk_user_create";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as ua ON ua.rowid=t.fk_user_assign";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "element_contact as ec ON ec.element_id=t.rowid";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_contact as tc ON ec.fk_c_type_contact=tc.rowid";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "socpeople sp ON ec.fk_socpeople=sp.rowid";
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "ticketsup_extrafields as ef on (t.rowid = ef.fk_object)";
}
$sql .= " WHERE t.entity IN (" . getEntity('ticketsup') . ")";
$sql .= " AND tc.source = 'external'";
$sql .= " AND tc.element='" . $object->dao->element . "'";
$sql .= " AND tc.active=1";
$sql .= " AND (sp.email='" . $db->escape($_SESSION['email_customer']) . "'";
$sql .= " OR s.email='" . $db->escape($_SESSION['email_customer']) . "'";
$sql .= " OR t.origin_email='" . $db->escape($_SESSION['email_customer']) . "')";
// Manage filter
if (!empty($filter)) {
foreach ($filter as $key => $value) {
if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
$sql .= ' AND ' . $key . ' = \'' . $value . '\'';
} elseif (($key == 't.fk_user_assign') || ($key == 't.type_code') || ($key == 't.category_code') || ($key == 't.severity_code')) {
$sql .= " AND " . $key . " = '" . $db->escape($value) ."'";
} elseif ($key == 't.fk_statut') {
if (is_array($value) && count($value) > 0) {
$sql .= 'AND ' . $key . ' IN (' . implode(',', $value) . ')';
} else {
$sql .= ' AND ' . $key . ' = ' . $db->escape($value);
}
} else {
$sql .= ' AND ' . $key . ' LIKE \'%' . $value . '%\'';
}
}
}
$sql .= " GROUP BY t.track_id";
$sql .= " ORDER BY " . $sortfield . ' ' . $sortorder;
$resql = $db->query($sql);
if ($resql) {
$num_total = $db->num_rows($resql);
if (!empty($limit)) {
$sql .= ' ' . $db->plimit($limit + 1, $offset);
}
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
print_barre_liste($langs->trans('TicketList'), $page, 'public/list.php', $param, $sortfield, $sortorder, '', $num, $num_total, 'ticketsup-32@ticketsup');
/*
* Search bar
*/
print '<form method="get" action="' . $url_form . '" id="searchFormList" >' . "\n";
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print '<input type="hidden" name="action" value="view_ticketlist">';
print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
$varpage = empty($contextpage) ? $url_page_current : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
print '<table class="liste ' . ($moreforfilter ? "listwithfilterbefore" : "") . '">';
print '<tr class="liste_titre">';
if (!empty($arrayfields['t.datec']['checked'])) {
print_liste_field_titre($arrayfields['t.datec']['label'], $url_page_current, 't.datec', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.date_read']['checked'])) {
print_liste_field_titre($arrayfields['t.date_read']['label'], $url_page_current, 't.date_read', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.date_close']['checked'])) {
print_liste_field_titre($arrayfields['t.date_close']['label'], $url_page_current, 't.date_close', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.ref']['checked'])) {
print_liste_field_titre($arrayfields['t.ref']['label'], $url_page_current, 't.ref', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.fk_statut']['checked'])) {
print_liste_field_titre($arrayfields['t.fk_statut']['label'], $url_page_current, 't.fk_statut', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.subject']['checked'])) {
print_liste_field_titre($arrayfields['t.subject']['label']);
}
if (!empty($arrayfields['type.code']['checked'])) {
print_liste_field_titre($arrayfields['type.code']['label'], $url_page_current, 'type.code', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['category.code']['checked'])) {
print_liste_field_titre($arrayfields['category.code']['label'], $url_page_current, 'category.code', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['severity.code']['checked'])) {
print_liste_field_titre($arrayfields['severity.code']['label'], $url_page_current, 'severity.code', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.progress']['checked'])) {
print_liste_field_titre($arrayfields['t.progress']['label'], $url_page_current, 't.progress', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.fk_user_create']['checked'])) {
print_liste_field_titre($arrayfields['t.fk_user_create']['label'], $url_page_current, 't.fk_user_create', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.fk_user_assign']['checked'])) {
print_liste_field_titre($arrayfields['t.fk_user_assign']['label'], $url_page_current, 't.fk_user_assign', '', $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.tms']['checked'])) {
print_liste_field_titre($arrayfields['t.tms']['label'], $url_page_current, 't.tms', '', $param, '', $sortfield, $sortorder);
}
// Extra fields
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) {
foreach ($extrafields->attribute_label as $key => $val) {
if (!empty($arrayfields["ef." . $key]['checked'])) {
$align = $extrafields->getAlignFlag($key);
print_liste_field_titre($extralabels[$key], $url_page_current, "ef." . $key, "", $param, ($align ? 'align="' . $align . '"' : ''), $sortfield, $sortorder);
}
}
}
print_liste_field_titre($selectedfields, $url_page_current, "", '', '', 'align="right"', $sortfield, $sortorder, 'maxwidthsearch ');
print '</tr>';
/*
* Filter bar
*/
$formTicket = new FormTicketsup($db);
print '<tr class="liste_titre">';
if (!empty($arrayfields['t.datec']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.date_read']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.date_close']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.ref']['checked'])) {
print '<td class="liste_titre"></td>';
}
// Status
if (!empty($arrayfields['t.fk_statut']['checked'])) {
print '<td>';
$selected = ($search_fk_status != "non_closed" ? $search_fk_status : '');
$object->printSelectStatus($selected);
print '</td>';
}
if (!empty($arrayfields['t.subject']['checked'])) {
print '<td class="liste_titre">';
print '<input type="text" class="flat" name="search_subject" value="' . $search_subject . '" size="20">';
print '</td>';
}
if (!empty($arrayfields['type.code']['checked'])) {
print '<td class="liste_titre">';
$formTicket->selectTypesTickets($search_type, 'search_type', '', 2, 1, 1);
print '</td>';
}
if (!empty($arrayfields['category.code']['checked'])) {
print '<td class="liste_titre">';
$formTicket->selectCategoriesTickets($search_category, 'search_category', '', 2, 1, 1);
print '</td>';
}
if (!empty($arrayfields['severity.code']['checked'])) {
print '<td class="liste_titre">';
$formTicket->selectSeveritiesTickets($search_severity, 'search_severity', '', 2, 1, 1);
print '</td>';
}
if (!empty($arrayfields['t.progress']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.fk_user_create']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.fk_user_assign']['checked'])) {
print '<td class="liste_titre"></td>';
}
if (!empty($arrayfields['t.tms']['checked'])) {
print '<td class="liste_titre"></td>';
}
// Extra fields
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) {
foreach ($extrafields->attribute_label as $key => $val) {
if (!empty($arrayfields["ef." . $key]['checked'])) {
print '<td class="liste_titre"></td>';
}
}
}
print '<td class="liste_titre" align="right">';
print '<input type="image" class="liste_titre" name="button_search" src="' . img_picto($langs->trans("Search"), 'search.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
print '<input type="image" class="liste_titre" name="button_removefilter" src="' . img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1) . '" value="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '" title="' . dol_escape_htmltag($langs->trans("RemoveFilter")) . '">';
print '</td>';
print '</tr>';
$var = true;
while ($obj = $db->fetch_object($resql)) {
$var = !$var;
print "<tr " . $bc[$var] . ">";
// Date ticket
if (!empty($arrayfields['t.datec']['checked'])) {
print '<td>';
print dol_print_date($obj->datec, 'dayhour');
print '</td>';
}
// Date read
if (!empty($arrayfields['t.date_read']['checked'])) {
print '<td>';
print dol_print_date($obj->date_read, 'dayhour');
print '</td>';
}
// Date close
if (!empty($arrayfields['t.date_close']['checked'])) {
print '<td>';
print dol_print_date($obj->date_close, 'dayhour');
print '</td>';
}
// ref
if (!empty($arrayfields['t.ref']['checked'])) {
print '<td>';
print $obj->ref;
print '</td>';
}
// Statut
if (!empty($arrayfields['t.fk_statut']['checked'])) {
print '<td>';
$object->fk_statut = $obj->fk_statut;
print $object->getLibStatut(2);
print '</td>';
}
// Subject
if (!empty($arrayfields['t.subject']['checked'])) {
print '<td>';
print '<a href="javascript:viewticket(\'' . $obj->track_id . '\',\'' . $_SESSION['email_customer'] . '\');">' . $obj->subject . '</a>';
print '</td>';
}
// Type
if (!empty($arrayfields['type.code']['checked'])) {
print '<td>';
print $obj->type_label;
print '</td>';
}
// Category
if (!empty($arrayfields['category.code']['checked'])) {
print '<td>';
print $obj->category_label;
print '</td>';
}
// Severity
if (!empty($arrayfields['severity.code']['checked'])) {
print '<td>';
print $obj->severity_label;
print '</td>';
}
// Progression
if (!empty($arrayfields['t.progress']['checked'])) {
print '<td>';
print $obj->progress;
print '</td>';
}
// Message author
if (!empty($arrayfields['t.fk_user_create']['checked'])) {
print '<td>';
if ($obj->fk_user_create) {
$user_create->firstname = (!empty($obj->user_create_firstname) ? $obj->user_create_firstname : '');
$user_create->name = (!empty($obj->user_create_lastname) ? $obj->user_create_lastname : '');
$user_create->id = (!empty($obj->fk_user_create) ? $obj->fk_user_create : '');
print $user_create->getFullName();
} else {
print $langs->trans('Email');
}
print '</td>';
}
// Assigned author
if (!empty($arrayfields['t.fk_user_assign']['checked'])) {
print '<td>';
if ($obj->fk_user_assign) {
$user_assign->firstname = (!empty($obj->user_assign_firstname) ? $obj->user_assign_firstname : '');
$user_assign->lastname = (!empty($obj->user_assign_lastname) ? $obj->user_assign_lastname : '');
$user_assign->id = (!empty($obj->fk_user_assign) ? $obj->fk_user_assign : '');
print $user_assign->getFullName();
} else {
print $langs->trans('None');
}
print '</td>';
}
if (!empty($arrayfields['t.tms']['checked'])) {
print '<td>' . dol_print_date($obj->tms, 'dayhour') . '</td>';
}
// Extra fields
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) {
foreach ($extrafields->attribute_label as $key => $val) {
if (!empty($arrayfields["ef." . $key]['checked'])) {
print '<td';
$align = $extrafields->getAlignFlag($key);
if ($align) {
print ' align="' . $align . '"';
}
print '>';
$tmpkey = 'options_' . $key;
print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1);
print '</td>';
}
}
}
print '<td></td>';
$i++;
print '</tr>';
}
print '</table>';
print '</form>';
print '<form method="post" id="form_view_ticket" name="form_view_ticket" enctype="multipart/form-data" action="' . dol_buildpath('/ticketsup/public/view.php', 1) . '" style="display:none;">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="view_ticket">';
print '<input type="hidden" name="btn_view_ticket_list" value="1">';
print '<input type="hidden" name="track_id" value="">';
print '<input type="hidden" name="email" value="">';
print "</form>";
print '<script type="text/javascript">
function viewticket(ticket_id, email) {
var form = $("#form_view_ticket");
form.find("input[name=\\"track_id\\"]").val(ticket_id);
form.find("input[name=\\"email\\"]").val(email);
form.submit();
}
</script>';
}
}
} else {
print '<div class="error">Not Allowed<br /><a href="' . $_SERVER['PHP_SELF'] . '?track_id=' . $object->dao->track_id . '">' . $langs->trans('Back') . '</a></div>';
}
} else {
print '<p style="text-align: center">' . $langs->trans("TicketPublicMsgViewLogIn") . '</p>';
print '<div id="form_view_ticket">';
print '<form method="post" name="form_view_ticketlist" enctype="multipart/form-data" action="' . $_SERVER['PHP_SELF'] . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="view_ticketlist">';
print '<input type="hidden" name="search_fk_status" value="non_closed">';
print '<p><label for="track_id" style="display: inline-block; width: 30%; "><span class="fieldrequired">' . $langs->trans("OneOfTicketTrackId") . '</span></label>';
print '<input size="30" id="track_id" name="track_id" value="' . (GETPOST('track_id', 'alpha') ? GETPOST('track_id', 'alpha') : '') . '" />';
print '</p>';
print '<p><label for="email" style="display: inline-block; width: 30%; "><span class="fieldrequired">' . $langs->trans('Email') . '</span></label>';
print '<input size="30" id="email" name="email" value="' . (GETPOST('email', 'alpha') ? GETPOST('email', 'alpha') : $_SESSION['customer_email']) . '" />';
print '</p>';
print '<p style="text-align: center; margin-top: 1.5em;">';
print '<input class="button" type="submit" name="btn_view_ticket_list" value="' . $langs->trans('ViewMyTicketList') . '" />';
print "</p>\n";
print "</form>\n";
print "</div>\n";
}
// End of page
llxFooter();
$db->close();

View File

@ -0,0 +1,337 @@
<?php
/* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/public/index.php
* \ingroup ticketsup
* \brief Public file to add and manage ticket
*/
if (!defined('NOCSRFCHECK')) {
define('NOCSRFCHECK', '1');
}
// Do not check anti CSRF attack test
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
// If there is no need to load and show top and left menu
if (!defined("NOLOGIN")) {
define("NOLOGIN", '1');
}
// If this page is public (can be called outside logged session)
// Change this following line to use the correct relative path (../, ../../, etc)
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = @include '../main.inc.php';
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include '../../main.inc.php';
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include '../../../main.inc.php';
}
if (!$res) {
die("Include of main fails");
}
// Change this following line to use the correct relative path from htdocs
dol_include_once('/ticketsup/class/actions_ticketsup.class.php');
dol_include_once('/ticketsup/class/html.formticketsup.class.php');
dol_include_once('/ticketsup/lib/ticketsup.lib.php');
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
// Get parameters
$track_id = GETPOST('track_id', 'alpha');
$action = GETPOST('action', 'alpha', 3);
$email = GETPOST('email', 'alpha');
if (GETPOST('btn_view_ticket')) {
unset($_SESSION['email_customer']);
}
if (isset($_SESSION['email_customer'])) {
$email = $_SESSION['email_customer'];
}
$object = new ActionsTicketsup($db);
if ($action == "view_ticket" || $action == "add_message" || $action == "close" || $action == "confirm_public_close" || $action == "new_public_message") {
$error = 0;
$display_ticket = false;
if (!strlen($track_id)) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketTrackId")));
$action = '';
}
if (!strlen($email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Email")));
$action = '';
} else {
if (!isValidEmail($email)) {
$error++;
array_push($object->errors, $langs->trans("ErrorEmailInvalid"));
$action = '';
}
}
if (!$error) {
$ret = $object->fetch('', $track_id);
if ($ret && $object->dao->id > 0) {
// vérifie si l'adresse email est bien dans les contacts du ticket
$contacts = $object->dao->liste_contact(-1, 'external');
foreach ($contacts as $contact) {
if ($contact['email'] == $email) {
$display_ticket = true;
$_SESSION['email_customer'] = $email;
break;
} else {
$display_ticket = false;
}
}
if ($object->dao->fk_soc > 0) {
$object->dao->fetch_thirdparty();
}
if ($email == $object->dao->origin_email || $email == $object->dao->thirdparty->email) {
$display_ticket = true;
$_SESSION['email_customer'] = $email;
}
} else {
$error++;
array_push($object->errors, $langs->trans("ErrorTicketNotFound", $track_id));
$action = '';
}
}
if ($error) {
setEventMessage($object->errors, 'errors');
$action = '';
}
}
$object->doActions($action);
/***************************************************
* VIEW
*
****************************************************/
$form = new Form($db);
$formticket = new FormTicketsup($db);
$arrayofjs = array();
$arrayofcss = array('/ticketsup/css/styles.css', '/ticketsup/css/bg.css.php');
llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss);
if (!$conf->global->TICKETS_ENABLE_PUBLIC_INTERFACE) {
print '<div class="error">' . $langs->trans('TicketPublicInterfaceForbidden') . '</div>';
$db->close();
exit();
}
print '<div style="margin: 0 auto; width:60%">';
if ($action == "view_ticket" || $action == "add_message" || $action == "close" || $action == "confirm_public_close") {
if ($display_ticket) {
// Confirmation close
if ($action == 'close') {
$ret = $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1);
if ($ret == 'html') {
print '<br>';
}
}
print '<div id="form_view_ticket">';
print '<table class="border" style="width:100%">';
// Ref
print '<tr><td style="width:40%">' . $langs->trans("Ref") . '</td><td>';
print $object->dao->ref;
print '</td></tr>';
// Tracking ID
print '<tr><td style="width:40%">' . $langs->trans("TicketTrackId") . '</td><td>';
print $object->dao->track_id;
print '</td></tr>';
// Subject
print '<tr><td><strong>' . $langs->trans("Subject") . '</strong></td><td>';
print $object->dao->subject;
print '</td></tr>';
// Statut
print '<tr><td>' . $langs->trans("Status") . '</td><td>';
print $object->dao->getLibStatut(2);
print '</td></tr>';
// Type
print '<tr><td>' . $langs->trans("Type") . '</td><td>';
print $object->dao->type_label;
print '</td></tr>';
// Category
print '<tr><td>' . $langs->trans("Category") . '</td><td>';
print $object->dao->category_label;
print '</td></tr>';
// Severity
print '<tr><td>' . $langs->trans("Severity") . '</td><td>';
print $object->dao->severity_label;
print '</td></tr>';
// Creation date
print '<tr><td>' . $langs->trans("DateCreation") . '</td><td>';
print dol_print_date($object->dao->datec, 'dayhour');
print '</td></tr>';
// Author
print '<tr><td>' . $langs->trans("Author") . '</td><td>';
if ($object->dao->fk_user_create > 0) {
$langs->load("users");
$fuser = new User($db);
$fuser->fetch($object->dao->fk_user_create);
print $fuser->getFullName($langs);
} else {
print $object->dao->origin_email;
}
print '</td></tr>';
// Read date
if (!empty($object->dao->date_read)) {
print '<tr><td>' . $langs->trans("TicketReadOn") . '</td><td>';
print dol_print_date($object->dao->date_read, 'dayhour');
print '</td></tr>';
}
// Close date
if (!empty($object->dao->date_close)) {
print '<tr><td>' . $langs->trans("TicketCloseOn") . '</td><td>';
print dol_print_date($object->dao->date_close, 'dayhour');
print '</td></tr>';
}
// User assigned
print '<tr><td>' . $langs->trans("UserAssignedTo") . '</td><td>';
if ($object->dao->fk_user_assign > 0) {
$fuser = new User($db);
$fuser->fetch($object->dao->fk_user_assign);
print $fuser->getFullName($langs, 1);
} else {
print $langs->trans('None');
}
print '</td></tr>';
// Progression
print '<tr><td>' . $langs->trans("Progression") . '</td><td>';
print ($object->dao->progress > 0 ? $object->dao->progress : '0') . '%';
print '</td></tr>';
print '</table>';
print '</div>';
print '<div style="clear: both; margin-top: 1.5em;"></div>';
if ($action == 'add_message') {
print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticketsup');
$formticket = new FormTicketsup($db);
$formticket->action = "new_public_message";
$formticket->track_id = $object->dao->track_id;
$formticket->id = $object->dao->id;
$formticket->param = array('fk_user_create' => '-1');
$formticket->withfile = 2;
$formticket->showMessageForm('100%');
} else {
print '<form method="post" id="form_view_ticket_list" name="form_view_ticket_list" enctype="multipart/form-data" action="' . dol_buildpath('/ticketsup/public/list.php', 1) . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="view_ticketlist">';
print '<input type="hidden" name="track_id" value="'.$object->dao->track_id.'">';
print '<input type="hidden" name="email" value="'.$_SESSION['email_customer'].'">';
print '<input type="hidden" name="search_fk_status" value="non_closed">';
print "</form>\n";
print '<div class="tabsAction">';
// List ticket
print '<div class="inline-block divButAction"><a class="butAction" href="javascript:$(\'#form_view_ticket_list\').submit();">' . $langs->trans('ViewMyTicketList') . '</a></div>';
if ($object->dao->fk_statut < 8) {
// New message
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=add_message&track_id=' . $object->dao->track_id . '">' . $langs->trans('AddMessage') . '</a></div>';
// Close ticket
if ($object->dao->fk_statut > 0 && $object->dao->fk_statut < 8) {
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=close&track_id=' . $object->dao->track_id . '">' . $langs->trans('CloseTicket') . '</a></div>';
}
}
print '</div>';
}
// Message list
print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticketsup');
$object->viewTicketMessages(false);
print '<br />';
// Logs list
print load_fiche_titre($langs->trans('TicketHistory'), '', 'history@ticketsup');
$object->viewTicketLogs(false);
} else {
print '<div class="error">Not Allowed<br /><a href="' . $_SERVER['PHP_SELF'] . '?track_id=' . $object->dao->track_id . '">' . $langs->trans('Back') . '</a></div>';
}
} else {
print '<p style="text-align: center">' . $langs->trans("TicketPublicMsgViewLogIn") . '</p>';
print '<div id="form_view_ticket">';
print '<form method="post" name="form_view_ticket" enctype="multipart/form-data" action="' . $_SERVER['PHP_SELF'] . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="view_ticket">';
print '<p><label for="track_id" style="display: inline-block; width: 30%; "><span class="fieldrequired">' . $langs->trans("TicketTrackId") . '</span></label>';
print '<input size="30" id="track_id" name="track_id" value="' . (GETPOST('track_id', 'alpha') ? GETPOST('track_id', 'alpha') : '') . '" />';
print '</p>';
print '<p><label for="email" style="display: inline-block; width: 30%; "><span class="fieldrequired">' . $langs->trans('Email') . '</span></label>';
print '<input size="30" id="email" name="email" value="' . (GETPOST('email', 'alpha') ? GETPOST('email', 'alpha') : $_SESSION['customer_email']) . '" />';
print '</p>';
print '<p style="text-align: center; margin-top: 1.5em;">';
print '<input class="button" type="submit" name="btn_view_ticket" value="' . $langs->trans('ViewTicket') . '" />';
print "</p>\n";
print "</form>\n";
print "</div>\n";
}
// End of page
llxFooter();
$db->close();

19
htdocs/ticketsup/.gitignore vendored Executable file
View File

@ -0,0 +1,19 @@
# Generated binaries
/build/*.zip
# Doxygen generated documentation
/build/doxygen/doxygen_warnings.log
/doc/code/doxygen
# Composer managed dependencies
/vendor/
/dev/bin
# PHPdocumentor generated files
/build/phpdoc
/doc/code/phpdoc
# Sphinx generated files
/doc/user/build
/.settings/
/.buildpath
/.project
/test/report
# PhpStorm generated files
/.idea/

View File

@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
[dolibarr_tickets.ticketsuplang]
file_filter = langs/<lang>/ticketsup.lang
source_file = langs/en_US/ticketsup.lang
source_lang = en_US
type = MOZILLAPROPERTIES

795
htdocs/ticketsup/card.php Normal file
View File

@ -0,0 +1,795 @@
<?php
/*
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* Card of ticket
*
* @package ticketsup
*/
// Change this following line to use the correct relative path (../, ../../, etc)
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once 'class/actions_ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
if (!empty($conf->projet->enabled)) {
include DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
}
if (!empty($conf->contrat->enabled)) {
include_once DOL_DOCUMENT_ROOT . '/core/lib/contract.lib.php';
include_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formcontract.class.php';
}
if (!class_exists('Contact')) {
include DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
}
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
// Get parameters
$id = GETPOST('id', 'int');
$track_id = GETPOST('track_id', 'alpha', 3);
$action = GETPOST('action', 'alpha', 3);
$ref = GETPOST('ref', 'alpha');
$projectid = GETPOST('projectid', 'int');
// Initialize technical object to manage hooks of ticketsup. Note that conf->hooks_modules contains array array
$hookmanager->initHooks(array('ticketsupcard','globalcard'));
$object = new ActionsTicketsup($db);
$object->doActions($action);
$extrafields = new ExtraFields($db);
$extralabels = $extrafields->fetch_name_optionals_label($object->dao->table_element);
if (!$action) {
$action = 'view';
}
//Select mail models is same action as add_message
if (GETPOST('modelselected')) {
$action = 'add_message';
}
// Store current page url
$url_page_current = dol_buildpath('/ticketsup/card.php', 1);
/***************************************************
* PAGE
*
****************************************************/
$userstat = new User($db);
$form = new Form($db);
$formticket = new FormTicketsup($db);
if ($action == 'view' || $action == 'add_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' || $action == 'editsubject' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') {
$res = $object->fetch($id, $track_id, $ref);
if ($res > 0) {
// Security check
$result = restrictedArea($user, 'ticketsup', $object->dao->id);
// or for unauthorized internals users
if (!$user->societe_id && ($conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY && $object->dao->fk_user_assign != $user->id) && !$user->rights->ticketsup->manage) {
accessforbidden('', 0);
}
$permissiondellink = $user->rights->ticketsup->write;
include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
$help_url = 'FR:DocumentationModuleTicket';
$page_title = $object->getTitle($action);
llxHeader('', $page_title, $help_url);
// Confirmation close
if ($action == 'close') {
print $form->formconfirm($url_page_current . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_close", '', '', 1);
if ($ret == 'html') {
print '<br>';
}
}
// Confirmation delete
if ($action == 'delete') {
print $form->formconfirm($url_page_current . "?track_id=" . $track_id, $langs->trans("Delete"), $langs->trans("ConfirmDeleteTicket"), "confirm_delete_ticket", '', '', 1);
}
// Confirm reopen
if ($action == 'reopen') {
print $form->formconfirm($url_page_current . '?track_id=' . $track_id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenTicket'), 'confirm_reopen', '', '', 1);
}
// Confirmation status change
if ($action == 'set_status') {
$new_status = GETPOST('new_status');
print $form->formconfirm($url_page_current . "?track_id=" . $track_id . "&new_status=" . GETPOST('new_status'), $langs->trans("TicketChangeStatus"), $langs->trans("TicketConfirmChangeStatus", $langs->transnoentities($object->dao->statuts_short[$new_status])), "confirm_set_status", '', '', 1);
}
// project info
if ($projectid) {
$projectstat = new Project($db);
if ($projectstat->fetch($projectid) > 0) {
$projectstat->fetch_thirdparty();
// To verify role of users
//$userAccess = $object->restrictedProjectArea($user,'read');
$userWrite = $projectstat->restrictedProjectArea($user, 'write');
//$userDelete = $object->restrictedProjectArea($user,'delete');
//print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
$head = project_prepare_head($projectstat);
dol_fiche_head($head, 'ticketsup', $langs->trans("Project"), 0, ($projectstat->public ? 'projectpub' : 'project'));
/*
* Projet synthese pour rappel
*/
print '<table class="border" width="100%">';
$linkback = '<a href="' . DOL_URL_ROOT . '/projet/list.php">' . $langs->trans("BackToList") . '</a>';
// Ref
print '<tr><td width="30%">' . $langs->trans('Ref') . '</td><td colspan="3">';
// Define a complementary filter for search of next/prev ref.
if (!$user->rights->projet->all->lire) {
$objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0);
$projectstat->next_prev_filter = " rowid in (" . (count($objectsListId) ? join(',', array_keys($objectsListId)) : '0') . ")";
}
print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', '');
print '</td></tr>';
// Label
print '<tr><td>' . $langs->trans("Label") . '</td><td>' . $projectstat->title . '</td></tr>';
// Customer
print "<tr><td>" . $langs->trans("ThirdParty") . "</td>";
print '<td colspan="3">';
if ($projectstat->thirdparty->id > 0) {
print $projectstat->thirdparty->getNomUrl(1);
} else {
print '&nbsp;';
}
print '</td></tr>';
// Visibility
print '<tr><td>' . $langs->trans("Visibility") . '</td><td>';
if ($projectstat->public) {
print $langs->trans('SharedProject');
} else {
print $langs->trans('PrivateProject');
}
print '</td></tr>';
// Statut
print '<tr><td>' . $langs->trans("Status") . '</td><td>' . $projectstat->getLibStatut(4) . '</td></tr>';
print "</table>";
print '</div>';
} else {
print "ErrorRecordNotFound";
}
} elseif ($object->dao->fk_soc > 0) {
$object->dao->fetch_thirdparty();
$head = societe_prepare_head($object->dao->thirdparty);
dol_fiche_head($head, 'ticketsup', $langs->trans("ThirdParty"), 0, 'company');
dol_banner_tab($object->dao->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
dol_fiche_end();
}
if (!$user->societe_id && $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY) {
$object->dao->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'";
} elseif ($user->societe_id > 0) {
$object->dao->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'";
}
$head = ticketsup_prepare_head($object->dao);
dol_fiche_head($head, 'tabTicketsup', $langs->trans("Ticket"), 0, 'ticketsup@ticketsup');
$object->dao->label = $object->dao->ref;
// Author
if ($object->dao->fk_user_create > 0) {
$object->dao->label .= ' - ' . $langs->trans("CreatedBy") . ' ';
$langs->load("users");
$fuser = new User($db);
$fuser->fetch($object->dao->fk_user_create);
$object->dao->label .= $fuser->getNomUrl(0);
}
if (!empty($object->dao->origin_email)) {
$object->dao->label .= ' - ' . $langs->trans("CreatedBy") . ' ';
$object->dao->label .= $object->dao->origin_email . ' <small>(' . $langs->trans("TicketEmailOriginIssuer") . ')</small>';
}
$linkback = '<a href="' . dol_buildpath('/ticketsup/list.php', 1) . '"><strong>' . $langs->trans("BackToList") . '</strong></a> ';
$object->dao->ticketsup_banner_tab('ref', '', ($user->societe_id ? 0 : 1), 'ref', 'subject', '', '', '', $morehtmlleft, $linkback);
print '<div class="fichecenter"><div class="fichehalfleft">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border centpercent">';
// Track ID
print '<tr><td class="titlefield">' . $langs->trans("TicketTrackId") . '</td><td>';
if (!empty($object->dao->track_id)) {
if (empty($object->dao->ref)) {
$object->ref = $object->dao->id;
print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'track_id');
} else {
print $object->dao->track_id;
}
} else {
print $langs->trans('None');
}
print '</td></tr>';
// Subject
print '<tr><td>';
print $form->editfieldkey("Subject", 'subject', $object->dao->subject, $object->dao, $user->rights->ticketsup->write && !$user->societe_id, 'string');
print '</td><td>';
print $form->editfieldval("Subject", 'subject', $object->dao->subject, $object->dao, $user->rights->ticketsup->write && !$user->societe_id, 'string');
print '</td></tr>';
// Creation date
print '<tr><td>' . $langs->trans("DateCreation") . '</td><td>';
print dol_print_date($object->dao->datec, 'dayhour');
print '</td></tr>';
// Read date
if (!empty($object->dao->date_read)) {
print '<tr><td>' . $langs->trans("TicketReadOn") . '</td><td>';
print dol_print_date($object->dao->date_read, 'dayhour');
print '</td></tr>';
print '<tr><td>' . $langs->trans("TicketTimeToRead") . '</td><td>';
print '<strong>' . convertSecondToTime($object->dao->date_read - $object->dao->datec) . '</strong>';
print '</td></tr>';
}
// Close date
if (!empty($object->dao->date_close)) {
print '<tr><td>' . $langs->trans("TicketCloseOn") . '</td><td>';
print dol_print_date($object->dao->date_close, 'dayhour');
print '</td></tr>';
}
print '</td></tr>';
// Customer
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td>';
print $langs->trans('Customer');
print '</td>';
if ($action != 'editcustomer' && $object->dao->fk_statut < 8 && !$user->societe_id && $user->rights->ticketsup->write) {
print '<td align="right"><a href="' . $url_page_current . '?action=editcustomer&amp;track_id=' . $object->dao->track_id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . '</a></td>';
}
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'editcustomer') {
$form->form_thirdparty($url_page_current . '?track_id=' . $object->dao->track_id, $object->dao->fk_soc, 'editcustomer', ($object->dao->fk_soc ? 's.rowid <> ' . $object->dao->fk_soc : ''), 1);
} else {
$form->form_thirdparty($url_page_current . '?track_id=' . $object->dao->track_id, $object->dao->fk_soc, 'none', 's.rowid <> ' . $object->dao->fk_soc, 1);
}
print '</td></tr>';
// Project
if (!empty($conf->projet->enabled)) {
$langs->load('projects');
print '<tr><td height="10">';
print '<table class="nobordernopadding" width="100%"><tr><td>';
print $langs->trans('Project');
print '</td>';
if ($action != 'classify' && $user->rights->ticketsup->write) {
print '<td align="right"><a href="' . $url_page_current . '?action=classify&amp;track_id=' . $object->dao->track_id . '">' . img_edit($langs->trans('SetProject')) . '</a></td>';
}
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'classify') {
$form->form_project($url_page_current . '?track_id=' . $object->dao->track_id, $object->dao->socid, $object->dao->fk_project, 'projectid');
} else {
$form->form_project($url_page_current . '?track_id=' . $object->dao->track_id, $object->dao->socid, $object->dao->fk_project, 'none');
}
print '</td></tr>';
}
// User assigned
print '<tr><td>' . $langs->trans("UserAssignedTo") . '</td><td>';
if ($object->dao->fk_user_assign > 0) {
$userstat->fetch($object->dao->fk_user_assign);
print $userstat->getNomUrl(1);
} else {
print $langs->trans('None');
}
// Show user list to assignate one if status is "read"
if (GETPOST('set') == "assign_ticket" && $object->dao->fk_statut < 8 && !$user->societe_id && $user->rights->ticketsup->write) {
print '<form method="post" name="ticketsup" enctype="multipart/form-data" action="' . $url_page_current . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="assign_user">';
print '<input type="hidden" name="track_id" value="' . $object->dao->track_id . '">';
print '<label for="fk_user_assign">' . $langs->trans("AssignUser") . '</label> ';
print $form->select_dolusers($user->id, 'fk_user_assign', 0);
print ' <input class="button" type="submit" name="btn_assign_user" value="' . $langs->trans("Validate") . '" />';
print '</form>';
}
if ($object->dao->fk_statut < 8 && GETPOST('set') != "assign_ticket" && $user->rights->ticketsup->manage) {
print '<a href="' . $url_page_current . '?track_id=' . $object->dao->track_id . '&action=view&set=assign_ticket">' . img_picto('', 'edit') . ' ' . $langs->trans('Modify') . '</a>';
}
print '</td></tr>';
// Progression
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
print $langs->trans('Progression') . '</td><td align="left">';
print '</td>';
if ($action != 'progression' && $object->dao->fk_statut < 8 && !$user->societe_id) {
print '<td align="right"><a href="' . $url_page_current . '?action=progression&amp;track_id=' . $object->dao->track_id . '">' . img_edit($langs->trans('Modify')) . '</a></td>';
}
print '</tr></table>';
print '</td><td colspan="5">';
if ($user->rights->ticketsup->write && $action == 'progression') {
print '<form action="' . $url_page_current . '" method="post">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="track_id" value="' . $track_id . '">';
print '<input type="hidden" name="action" value="set_progression">';
print '<input type="text" class="flat" size="20" name="progress" value="' . $object->dao->progress . '">';
print ' <input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
print '</form>';
} else {
print($object->dao->progress > 0 ? $object->dao->progress : '0') . '%';
}
print '</td>';
print '</tr>';
// Timing (Duration sum of linked fichinter
$object->dao->fetchObjectLinked();
$num = count($object->dao->linkedObjects);
$timing = 0;
if ($num) {
foreach ($object->dao->linkedObjects as $objecttype => $objects) {
if ($objecttype = "fichinter") {
foreach ($objects as $fichinter) {
$timing += $fichinter->duration;
}
}
}
}
print '<tr><td valign="top">';
print $form->textwithpicto($langs->trans("TicketDurationAuto"), $langs->trans("TicketDurationAutoInfos"), 1);
print '</td><td>';
print convertSecondToTime($timing, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
print '</td></tr>';
// Other attributes
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook) && !empty($extrafields->attribute_label)) {
if ($action == "edit_extrafields") {
print '<form method="post" name="form_edit_extrafields" enctype="multipart/form-data" action="' . $url_page_current . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="set_extrafields">';
print '<input type="hidden" name="track_id" value="' . $object->dao->track_id . '">';
print $object->dao->showOptionals($extrafields, 'edit');
print '<tr><td colspan="2" align="center">';
print ' <input class="button" type="submit" name="btn_edit_extrafields" value="' . $langs->trans("Modify") . '" />';
print ' <input class="button" type="submit" name="cancel" value="' . $langs->trans("Cancel") . '" />';
print '</tr>';
print '</form>';
} else {
print $object->dao->showOptionals($extrafields);
if ($user->rights->ticketsup->write) {
print '<tr><td colspan="2" align="center">';
print '<a href="' . $url_page_current . '?track_id=' . $object->dao->track_id . '&action=edit_extrafields">' . img_picto('', 'edit') . ' ' . $langs->trans('Edit') . '</a>';
print '</tr>';
}
}
}
print '</table>';
// View Original message
$object->viewTicketOriginalMessage($user, $action);
// Fin colonne gauche et début colonne droite
print '</div><div class="fichehalfright"><div class="ficheaddleft">';
/***************************************************
*
* Classification and actions on ticket
*
***************************************************/
/*
* Ticket properties
*/
print '<table class="border" style="width:100%;" >';
print '<tr class="liste_titre">';
print '<td colspan="2">';
print $langs->trans('Properties');
print '</td>';
print '</tr>';
if (GETPOST('set') == 'properties' && $user->rights->ticketsup->write) {
/*
* Form to change ticket properties
*/
$j = 0;
$ticketprop[$j] = array(
'dict' => 'type',
'list_function' => 'selectTypesTickets',
'label' => 'TicketChangeType',
);
$j++;
$ticketprop[$j] = array(
'dict' => 'category',
'list_function' => 'selectCategoriesTickets',
'label' => 'TicketChangeCategory',
);
$j++;
$ticketprop[$j] = array(
'dict' => 'severity',
'list_function' => 'selectSeveritiesTickets',
'label' => 'TicketChangeSeverity',
);
foreach ($ticketprop as $property) {
print '<tr>';
print '<td>';
print '<form method="post" name="ticketsup" action="' . $url_page_current . '">';
print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
print '<input type="hidden" name="action" value="change_property">';
print '<input type="hidden" name="property" value="' . $property['dict'] . '">';
print '<input type="hidden" name="track_id" value="' . $track_id . '">';
print '<table class="nobordernopadding" style="width:100%;">';
print '<tr>';
print '<td width="40%">';
print '<label for="type_code">' . $langs->trans($property['label']) . '</label> ';
print '</td><td width="50%">';
print $formticket->{$property['list_function']}($object->dao->type_code, 'update_value', '', 0);
print '</td><td>';
print ' <input class="button" type="submit" name="btn_update_ticket_prop" value="' . $langs->trans("Modify") . '" />';
print '</td>';
print '</tr></table>';
print '</form>';
print '</td>';
print '</tr>';
}
} else {
// Type
print '<tr><td width="40%">' . $langs->trans("Type") . '</td><td>';
print $object->dao->type_label;
if ($user->admin && !$noadmininfo) {
print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
}
print '</td></tr>';
// Category
print '<tr><td>' . $langs->trans("Category") . '</td><td>';
print $object->dao->category_label;
if ($user->admin && !$noadmininfo) {
print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
}
print '</td></tr>';
// Severity
print '<tr><td>' . $langs->trans("TicketSeverity") . '</td><td>';
print $object->dao->severity_label;
if ($user->admin && !$noadmininfo) {
print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
}
print '</td></tr>';
}
print '</table>'; // End table actions
// Display navbar with links to change ticket status
if (!$user->societe_id && $user->rights->ticketsup->write && $object->dao->fk_status < 8 && GETPOST('set') !== 'properties') {
$object->viewStatusActions();
}
print load_fiche_titre($langs->trans('Contacts'), '', 'title_companies.png');
print '<div class="tagtable centpercent noborder allwidth">';
print '<div class="tagtr liste_titre">';
print '<div class="tagtd ">' . $langs->trans("Source") . '</div>
<div class="tagtd">' . $langs->trans("Company") . '</div>
<div class="tagtd">' . $langs->trans("Contacts") . '</div>
<div class="tagtd">' . $langs->trans("ContactType") . '</div>
<div class="tagtd">' . $langs->trans("Phone") . '</div>
<div class="tagtd" align="center">' . $langs->trans("Status") . '</div>';
print '</div><!-- tagtr -->';
// Contact list
$companystatic = new Societe($db);
$contactstatic = new Contact($db);
$userstatic = new User($db);
foreach (array('internal', 'external') as $source) {
$tmpobject = $object->dao;
$tab = $tmpobject->liste_contact(-1, $source);
$num = count($tab);
$i = 0;
while ($i < $num) {
$var = !$var;
print '<div class="tagtr ' . ($var ? 'pair' : 'impair') . '">';
print '<div class="tagtd" align="left">';
if ($tab[$i]['source'] == 'internal') {
echo $langs->trans("User");
}
if ($tab[$i]['source'] == 'external') {
echo $langs->trans("ThirdPartyContact");
}
print '</div>';
print '<div class="tagtd" align="left">';
if ($tab[$i]['socid'] > 0) {
$companystatic->fetch($tab[$i]['socid']);
echo $companystatic->getNomUrl(1);
}
if ($tab[$i]['socid'] < 0) {
echo $conf->global->MAIN_INFO_SOCIETE_NOM;
}
if (!$tab[$i]['socid']) {
echo '&nbsp;';
}
print '</div>';
print '<div class="tagtd">';
if ($tab[$i]['source'] == 'internal') {
if ($userstatic->fetch($tab[$i]['id'])) {
print $userstatic->getNomUrl(1);
}
}
if ($tab[$i]['source'] == 'external') {
if ($contactstatic->fetch($tab[$i]['id'])) {
print $contactstatic->getNomUrl(1);
}
}
print ' </div>
<div class="tagtd">' . $tab[$i]['libelle'] . '</div>';
print '<div class="tagtd">';
print dol_print_phone($tab[$i]['phone'], '', '', '', AC_TEL).'<br>';
if (! empty($tab[$i]['phone_perso'])) {
//print img_picto($langs->trans('PhonePerso'),'object_phoning.png','',0,0,0).' ';
print '<br>'.dol_print_phone($tab[$i]['phone_perso'], '', '', '', AC_TEL).'<br>';
}
if (! empty($tab[$i]['phone_mobile'])) {
//print img_picto($langs->trans('PhoneMobile'),'object_phoning.png','',0,0,0).' ';
print dol_print_phone($tab[$i]['phone_mobile'], '', '', '', AC_TEL).'<br>';
}
print '</div>';
print '<div class="tagtd" align="center">';
if ($object->statut >= 0) {
echo '<a href="contacts.php?track_id=' . $object->dao->track_id . '&amp;action=swapstatut&amp;ligne=' . $tab[$i]['rowid'] . '">';
}
if ($tab[$i]['source'] == 'internal') {
$userstatic->id = $tab[$i]['id'];
$userstatic->lastname = $tab[$i]['lastname'];
$userstatic->firstname = $tab[$i]['firstname'];
echo $userstatic->LibStatut($tab[$i]['statuscontact'], 3);
}
if ($tab[$i]['source'] == 'external') {
$contactstatic->id = $tab[$i]['id'];
$contactstatic->lastname = $tab[$i]['lastname'];
$contactstatic->firstname = $tab[$i]['firstname'];
echo $contactstatic->LibStatut($tab[$i]['statuscontact'], 3);
}
if ($object->statut >= 0) {
echo '</a>';
}
print '</div>';
print '</div><!-- tagtr -->';
$i++;
}
}
print '</div><!-- contact list -->';
// Contract
if ($action == 'sel_contract') {
if (!empty($conf->contrat->enabled)) {
$langs->load('contrats');
print load_fiche_titre($langs->trans('LinkToAContract'), '', 'title_commercial.png');
$form_contract = new FormContract($db);
$form_contract->formSelectContract(
$url_page_current.'?track_id='.$object->dao->track_id,
$object->dao->fk_soc,
GETPOST('contractid'),
'contractid'
);
}
}
print '</div></div></div>';
print '<div style="clear:both"></div>';
print dol_fiche_end();
/* ActionBar */
print '<div class="tabsAction">';
// Show button to mark as read
if (($object->dao->fk_statut == '0' || empty($object->dao->date_read)) && !$user->societe_id) {
print '<div class="inline-block divButAction">';
print '<a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=mark_ticket_read">' . img_picto('', 'mark-read@ticketsup') . ' ' . $langs->trans('MarkAsRead') . '</a>';
print '</div';
}
// Show link to add a message (if read and not closed)
if ($object->dao->fk_statut < 8 && $action != "add_message") {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=add_message">' . $langs->trans('TicketAddMessage') . '</a></div>';
}
// Link to create an intervention
// socid is needed otherwise fichinter ask it and forgot origin after form submit :\
if (!$object->dao->fk_soc && $user->rights->ficheinter->creer) {
print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="' . $langs->trans('UnableToCreateInterIfNoSocid') . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
}
if ($object->dao->fk_soc > 0 && $object->dao->fk_statut < 8 && $user->rights->ficheinter->creer) {
print '<div class="inline-block divButAction"><a class="butAction" href="' . dol_buildpath('/fichinter/card.php', 1) . '?action=create&socid=' . $object->dao->fk_soc . '&origin=ticketsup_ticketsup&originid=' . $object->dao->id . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
}
// Button to edit Properties
if ($object->dao->fk_statut < 5 && $user->rights->ticketsup->write) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=view&set=properties">' . $langs->trans('TicketEditProperties') . '</a></div>';
}
// Button to link to a contract
if ($user->rights->ticketsup->write && $object->dao->fk_statut < 5 && $user->rights->contrat->creer) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=sel_contract">' . $langs->trans('LinkToAContract') . '</a></div>';
}
// Close ticket if statut is read
if ($object->dao->fk_statut > 0 && $object->dao->fk_statut < 8 && $user->rights->ticketsup->write) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=close">' . $langs->trans('CloseTicket') . '</a></div>';
}
// Re-open ticket
if (!$user->socid && $object->dao->fk_statut == 8 && !$user->societe_id) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->dao->track_id . '&action=reopen">' . $langs->trans('ReOpen') . '</a></div>';
}
// Delete ticket
if ($user->rights->ticketsup->delete && !$user->societe_id) {
print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?track_id=' . $object->dao->track_id . '&action=delete">' . $langs->trans('Delete') . '</a></div>';
}
print '</div>';
if ($action == 'view' || $action == 'edit_message_init') {
print '<div class="fichecenter">'
. '<div class="">';
//print '<div style="float: left; width:49%; margin-right: 1%;">';
// Message list
print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticketsup');
$show_private_message = ($user->societe_id ? 0 : 1);
$object->viewTicketTimelineMessages($show_private_message);
print '</div><!-- fichehalfleft --> ';
print '</div><!-- fichecenter -->';
print '<br style="clear: both">';
} elseif ($action == 'add_message') {
$action='new_message';
$modelmail='ticketsup_send';
print '<div>';
print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticketsup');
// Define output language
$outputlangs = $langs;
$newlang = '';
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) {
$newlang = $_REQUEST['lang_id'];
}
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
$newlang = $object->default_lang;
}
$formticket = new FormTicketsup($db);
$formticket->action = $action;
$formticket->track_id = $object->dao->track_id;
$formticket->id = $object->dao->id;
$formticket->withfile = 2;
$formticket->param = array('fk_user_create' => $user->id);
$formticket->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang);
// Tableau des parametres complementaires du post
$formticket->param['models']=$modelmail;
$formticket->param['models_id']=GETPOST('modelmailselected', 'int');
//$formticket->param['socid']=$object->dao->fk_soc;
$formticket->param['returnurl']=$_SERVER["PHP_SELF"].'?track_id='.$object->dao->track_id;
$formticket->withsubstit = 1;
if ($object->dao->fk_soc > 0) {
$object->dao->fetch_thirdparty();
$formticket->substit['__THIRDPARTY_NAME__'] = $object->dao->thirdparty->name;
}
$formticket->substit['__SIGNATURE__'] = $user->signature;
$formticket->substit['__TICKETSUP_TRACKID__'] = $object->dao->track_id;
$formticket->substit['__TICKETSUP_REF__'] = $object->dao->ref;
$formticket->substit['__TICKETSUP_SUBJECT__'] = $object->dao->subject;
$formticket->substit['__TICKETSUP_TYPE__'] = $object->dao->type_code;
$formticket->substit['__TICKETSUP_CATEGORY__'] = $object->dao->category_code;
$formticket->substit['__TICKETSUP_SEVERITY__'] = $object->dao->severity_code;
$formticket->substit['__TICKETSUP_MESSAGE__'] = $object->dao->message;
$formticket->substit['__TICKETSUP_PROGRESSION__'] = $object->dao->progress;
if ($object->dao->fk_user_assign > 0) {
$userstat->fetch($object->dao->fk_user_assign);
$formticket->substit['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
}
if ($object->dao->fk_user_create > 0) {
$userstat->fetch($object->dao->fk_user_create);
$formticket->substit['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
}
$formticket->showMessageForm('100%');
print '</div>';
}
}
} // End action view
/***************************************************
* LINKED OBJECT BLOCK
*
* Put here code to view linked object
****************************************************/
$somethingshown = $form->showLinkedObjectBlock($object->dao);
// End of page
llxFooter('');
$db->close();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
<?php
/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
/**
* API class for ticketsup types
*
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
class DictionaryTicketsupCategories extends DolibarrApi
{
private $translations = null;
/**
* Constructor
*/
function __construct()
{
global $db;
$this->db = $db;
}
/**
* Get the list of ticketsup types.
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @param int $limit Number of items per page
* @param int $page Page number (starting from zero)
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of events types
*
* @throws RestException
*/
function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
{
$list = array();
$sql = "SELECT rowid, code, pos, label, use_default, description";
$sql.= " FROM ".MAIN_DB_PREFIX."c_ticketsup_category as t";
$sql.= " WHERE t.active = 1";
// Add sql filters
if ($sqlfilters)
{
if (! DolibarrApi::_checkFilters($sqlfilters))
{
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
}
$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
}
$sql.= $this->db->order($sortfield, $sortorder);
if ($limit) {
if ($page < 0) {
$page = 0;
}
$offset = $limit * $page;
$sql .= $this->db->plimit($limit, $offset);
}
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
$min = min($num, ($limit <= 0 ? $num : $limit));
for ($i = 0; $i < $min; $i++) {
$list[] = $this->db->fetch_object($result);
}
} else {
throw new RestException(503, 'Error when retrieving list of ticketsup categories : '.$this->db->lasterror());
}
return $list;
}
}

View File

@ -0,0 +1,100 @@
<?php
/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
/**
* API class for ticketsup severities
*
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
class DictionaryTicketsupSeverities extends DolibarrApi
{
private $translations = null;
/**
* Constructor
*/
function __construct()
{
global $db;
$this->db = $db;
}
/**
* Get the list of ticketsup types.
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @param int $limit Number of items per page
* @param int $page Page number (starting from zero)
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of events types
*
* @throws RestException
*/
function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
{
$list = array();
$sql = "SELECT rowid, code, pos, label, use_default, color, description";
$sql.= " FROM ".MAIN_DB_PREFIX."c_ticketsup_severity as t";
$sql.= " WHERE t.active = 1";
// Add sql filters
if ($sqlfilters)
{
if (! DolibarrApi::_checkFilters($sqlfilters))
{
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
}
$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
}
$sql.= $this->db->order($sortfield, $sortorder);
if ($limit) {
if ($page < 0) {
$page = 0;
}
$offset = $limit * $page;
$sql .= $this->db->plimit($limit, $offset);
}
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
$min = min($num, ($limit <= 0 ? $num : $limit));
for ($i = 0; $i < $min; $i++) {
$list[] = $this->db->fetch_object($result);
}
} else {
throw new RestException(503, 'Error when retrieving list of ticketsup severities : '.$this->db->lasterror());
}
return $list;
}
}

View File

@ -0,0 +1,102 @@
<?php
/* Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
/**
* API class for ticketsup types
*
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*/
class DictionaryTicketsupTypes extends DolibarrApi
{
private $translations = null;
/**
* Constructor
*/
function __construct()
{
global $db;
$this->db = $db;
}
/**
* Get the list of ticketsup types.
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @param int $limit Number of items per page
* @param int $page Page number (starting from zero)
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return List of events types
*
* @throws RestException
*/
function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
{
$list = array();
$sql = "SELECT rowid, code, pos, label, use_default, description";
$sql.= " FROM ".MAIN_DB_PREFIX."c_ticketsup_type as t";
$sql.= " WHERE t.active = 1";
if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
// Add sql filters
if ($sqlfilters)
{
if (! DolibarrApi::_checkFilters($sqlfilters))
{
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
}
$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
}
$sql.= $this->db->order($sortfield, $sortorder);
if ($limit) {
if ($page < 0) {
$page = 0;
}
$offset = $limit * $page;
$sql .= $this->db->plimit($limit, $offset);
}
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
$min = min($num, ($limit <= 0 ? $num : $limit));
for ($i = 0; $i < $min; $i++) {
$list[] = $this->db->fetch_object($result);
}
} else {
throw new RestException(503, 'Error when retrieving list of ticketsup types : '.$this->db->lasterror());
}
return $list;
}
}

View File

@ -0,0 +1,543 @@
<?php
/* Copyright (C) 2016 Jean-François Ferry <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
use Luracast\Restler\RestException;
require 'ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
/**
* API class for ticketsup object
*
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*
*
*/
class Ticketsups extends DolibarrApi
{
/**
* @var array $FIELDS Mandatory fields, checked when create and update object
*/
public static $FIELDS = array(
'subject',
'message'
);
/**
* @var array $FIELDS_MESSAGES Mandatory fields, checked when create and update object
*/
public static $FIELDS_MESSAGES = array(
'track_id',
'message'
);
/**
* @var Ticketsup $ticketsup {@type Ticketsup}
*/
public $ticketsup;
/**
* Constructor
*
* @url GET ticketsup/
*
*/
public function __construct()
{
global $db;
$this->db = $db;
$this->ticketsup = new Ticketsup($this->db);
}
/**
* Get properties of a ticketsup object
*
* Return an array with ticketsup informations
*
* @param int $id ID of ticketsup
* @param string $track_id Tracking ID of ticket
* @param string $ref Reference for ticket
* @return array|mixed data without useless information
*
* @url GET track_id/{track_id}
* @url GET ref/{ref}
* @url GET {id}
* @throws RestException
*/
public function get($id = 0, $track_id = '', $ref = '')
{
if (! DolibarrApiAccess::$user->rights->ticketsup->read) {
throw new RestException(401);
}
// Check parameters
if (!$id && !$track_id && !$ref) {
throw new RestException(401, 'Wrong parameters');
}
$result = $this->ticketsup->fetch($id, $track_id, $ref);
if (! $result) {
throw new RestException(404, 'Ticketsup not found');
}
// String for user assigned
if ($this->ticketsup->fk_user_assign > 0) {
$userStatic = new User($this->db);
$userStatic->fetch($this->ticketsup->fk_user_assign);
$this->ticketsup->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
}
// Messages of ticket
$messages = array();
$this->ticketsup->loadCacheMsgsTicket();
if (is_array($this->ticketsup->cache_msgs_ticket) && count($this->ticketsup->cache_msgs_ticket) > 0) {
$num = count($this->ticketsup->cache_msgs_ticket);
$i = 0;
while ($i < $num) {
if ($this->ticketsup->cache_msgs_ticket[$i]['fk_user_action'] > 0) {
$user_action = new User($this->db);
$user_action->fetch($this->ticketsup->cache_msgs_ticket[$i]['fk_user_action']);
}
// Now define messages
$messages[] = array(
'id' => $this->ticketsup->cache_msgs_ticket[$i]['id'],
'fk_user_action' => $this->ticketsup->cache_msgs_ticket[$i]['fk_user_action'],
'fk_user_action_socid' => $user_action->socid,
'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname),
'message' => $this->ticketsup->cache_msgs_ticket[$i]['message'],
'datec' => $this->ticketsup->cache_msgs_ticket[$i]['datec'],
'private' => $this->ticketsup->cache_msgs_ticket[$i]['private']
);
$i++;
}
$this->ticketsup->messages = $messages;
}
// History
$history = array();
$this->ticketsup->loadCacheLogsTicket();
if (is_array($this->ticketsup->cache_logs_ticket) && count($this->ticketsup->cache_logs_ticket) > 0) {
$num = count($this->ticketsup->cache_logs_ticket);
$i = 0;
while ($i < $num) {
if ($this->ticketsup->cache_logs_ticket[$i]['fk_user_create'] > 0) {
$user_action = new User($this->db);
$user_action->fetch($this->ticketsup->cache_logs_ticket[$i]['fk_user_create']);
}
// Now define messages
$history[] = array(
'id' => $this->ticketsup->cache_logs_ticket[$i]['id'],
'fk_user_action' => $this->ticketsup->cache_logs_ticket[$i]['fk_user_create'],
'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname),
'message' => $this->ticketsup->cache_logs_ticket[$i]['message'],
'datec' => $this->ticketsup->cache_logs_ticket[$i]['datec'],
);
$i++;
}
$this->ticketsup->history = $history;
}
if (! DolibarrApi::_checkAccessToResource('ticketsup', $this->ticketsup->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
return $this->_cleanObjectDatas($this->ticketsup);
}
/**
* List ticketsups
*
* Get a list of ticketsups
*
* @param int $socid Filter list with thirdparty ID
* @param string $mode Use this param to filter list
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @param int $limit Limit for list
* @param int $page Page number
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
*
* @return array Array of ticketsup objects
*
*/
public function index($socid = 0, $mode = "", $sortfield = "s.rowid", $sortorder = "ASC", $limit = 0, $page = 0, $sqlfilters = '')
{
global $db, $conf;
$obj_ret = array();
if (!$socid && DolibarrApiAccess::$user->societe_id) {
$socid = DolibarrApiAccess::$user->societe_id;
}
// If the internal user must only see his customers, force searching by him
if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
$search_sale = DolibarrApiAccess::$user->id;
}
$sql = "SELECT s.rowid";
if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
$sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
}
$sql.= " FROM ".MAIN_DB_PREFIX."ticketsup as s";
if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
$sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
}
$sql.= ' WHERE s.entity IN ('.getEntity('ticketsup', 1).')';
if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
$sql.= " AND s.fk_soc = sc.fk_soc";
}
if ($socid > 0) {
$sql.= " AND s.fk_soc = ".$socid;
}
if ($search_sale > 0) {
$sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
}
// Example of use $mode
if ($mode == 'new') {
$sql.= " AND s.fk_statut IN (0)";
}
if ($mode == 'read') {
$sql.= " AND s.fk_statut IN (1)";
}
if ($mode == 'answered') {
$sql.= " AND s.fk_statut IN (3)";
}
if ($mode == 'assign') {
$sql.= " AND s.fk_statut IN (4)";
}
if ($mode == 'inprogress') {
$sql.= " AND s.fk_statut IN (5)";
}
if ($mode == 'waiting') {
$sql.= " AND s.fk_statut IN (6)";
}
if ($mode == 'closed') {
$sql.= " AND s.fk_statut IN (8)";
}
if ($mode == 'deleted') {
$sql.= " AND s.fk_statut IN (9)";
}
// Insert sale filter
if ($search_sale > 0) {
$sql .= " AND sc.fk_user = ".$search_sale;
}
// Add sql filters
if ($sqlfilters) {
if (! DolibarrApi::_checkFilters($sqlfilters)) {
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
}
$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
}
$sql.= $db->order($sortfield, $sortorder);
$nbtotalofrecords = 0;
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$result = $db->query($sql);
$nbtotalofrecords = $db->num_rows($result);
}
if ($limit) {
if ($page < 0) {
$page = 0;
}
$offset = $limit * $page;
$sql.= $db->plimit($limit + 1, $offset);
}
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
while ($i < $num) {
$obj = $db->fetch_object($result);
$ticketsup_static = new Ticketsup($db);
if ($ticketsup_static->fetch($obj->rowid)) {
if ($ticketsup_static->fk_user_assign > 0) {
$userStatic = new User($this->db);
$userStatic->fetch($ticketsup_static->fk_user_assign);
$ticketsup_static->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname;
}
$obj_ret[] = $this->_cleanObjectDatas($ticketsup_static);
}
$i++;
}
} else {
throw new RestException(503, 'Error when retrieve ticketsup list');
}
if (! count($obj_ret)) {
throw new RestException(404, 'No ticketsup found');
}
return $obj_ret;
}
/**
* Create ticketsup object
*
* @param array $request_data Request datas
* @return int ID of ticketsup
*
*/
public function post($request_data = null)
{
$ticketstatic = new Ticketsup($this->db);
if (! DolibarrApiAccess::$user->rights->ticketsup->create) {
throw new RestException(401);
}
// Check mandatory fields
$result = $this->_validate($request_data);
foreach ($request_data as $field => $value) {
$this->ticketsup->$field = $value;
}
if (empty($this->ticketsup->ref)) {
$this->ticketsup->ref = $ticketstatic->getDefaultRef();
}
if (empty($this->ticketsup->track_id)) {
$this->ticketsup->track_id = generate_random_id(16);
}
if (! $this->ticketsup->create(DolibarrApiAccess::$user)) {
throw new RestException(500);
}
return $this->ticketsup->id;
}
/**
* Create ticketsup object
*
* @param array $request_data Request datas
* @return int ID of ticketsup
*
*/
public function postNewMessage($request_data = null)
{
$ticketstatic = new Ticketsup($this->db);
if (! DolibarrApiAccess::$user->rights->ticketsup->create) {
throw new RestException(401);
}
// Check mandatory fields
$result = $this->_validateMessage($request_data);
foreach ($request_data as $field => $value) {
$this->ticketsup->$field = $value;
}
$ticketMessageText = $this->ticketsup->message;
$result = $this->ticketsup->fetch('', $this->ticketsup->track_id);
if (! $result) {
throw new RestException(404, 'Ticketsup not found');
}
$this->ticketsup->message = $ticketMessageText;
if (! $this->ticketsup->createTicketMessage(DolibarrApiAccess::$user)) {
throw new RestException(500);
}
return $this->ticketsup->id;
}
/**
* Update ticketsup
*
* @param int $id Id of ticketsup to update
* @param array $request_data Datas
* @return int
*
*/
public function put($id, $request_data = null)
{
if (! DolibarrApiAccess::$user->rights->ticketsup->create) {
throw new RestException(401);
}
$result = $this->ticketsup->fetch($id);
if (! $result) {
throw new RestException(404, 'Ticketsup not found');
}
if (! DolibarrApi::_checkAccessToResource('ticketsup', $this->ticketsup->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
foreach ($request_data as $field => $value) {
$this->ticketsup->$field = $value;
}
if ($this->ticketsup->update($id, DolibarrApiAccess::$user)) {
return $this->get($id);
}
return false;
}
/**
* Delete ticketsup
*
* @param int $id Ticketsup ID
* @return array
*
*/
public function delete($id)
{
if (! DolibarrApiAccess::$user->rights->ticketsup->supprimer) {
throw new RestException(401);
}
$result = $this->ticketsup->fetch($id);
if (! $result) {
throw new RestException(404, 'Ticketsup not found');
}
if (! DolibarrApi::_checkAccessToResource('ticketsup', $this->ticketsup->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
if (!$this->ticketsup->delete($id)) {
throw new RestException(500);
}
return array(
'success' => array(
'code' => 200,
'message' => 'Ticketsup deleted'
)
);
}
/**
* Validate fields before create or update object
*
* @param array $data Data to validate
* @return array
*
* @throws RestException
*/
private function _validate($data)
{
$ticketsup = array();
foreach (Ticketsups::$FIELDS as $field) {
if (!isset($data[$field])) {
throw new RestException(400, "$field field missing");
}
$ticketsup[$field] = $data[$field];
}
return $ticketsup;
}
/**
* Validate fields before create or update object message
*
* @param array $data Data to validate
* @return array
*
* @throws RestException
*/
private function _validateMessage($data)
{
$ticketsup = array();
foreach (Ticketsups::$FIELDS_MESSAGES as $field) {
if (!isset($data[$field])) {
throw new RestException(400, "$field field missing");
}
$ticketsup[$field] = $data[$field];
}
return $ticketsup;
}
/**
* Clean sensible object datas
*
* @param object $object Object to clean
* @return array Array of cleaned object properties
*
* @todo use an array for properties to clean
*
*/
public function _cleanObjectDatas($object)
{
// Remove $db object property for object
unset($object->db);
$attr2clean = array(
"contact",
"contact_id",
"ref_previous",
"ref_next",
"ref_ext",
"table_element_line",
"statut",
"country",
"country_id",
"country_code",
"barcode_type",
"barcode_type_code",
"barcode_type_label",
"barcode_type_coder",
"mode_reglement_id",
"cond_reglement_id",
"cond_reglement",
"fk_delivery_address",
"shipping_method_id",
"modelpdf",
"fk_account",
"note_public",
"note_private",
"note",
"total_ht",
"total_tva",
"total_localtax1",
"total_localtax2",
"total_ttc",
"fk_incoterms",
"libelle_incoterms",
"location_incoterms",
"name",
"lastname",
"firstname",
"civility_id",
"cache_msgs_ticket",
"cache_logs_ticket"
);
foreach ($attr2clean as $toclean) {
unset($object->$toclean);
}
// If object has lines, remove $db property
if (isset($object->lines) && count($object->lines) > 0) {
$nboflines = count($object->lines);
for ($i=0; $i < $nboflines; $i++) {
$this->_cleanObjectDatas($object->lines[$i]);
}
}
// If object has linked objects, remove $db property
if (isset($object->linkedObjects) && count($object->linkedObjects) > 0) {
foreach ($object->linkedObjects as $type_object => $linked_object) {
foreach ($linked_object as $object2clean) {
$this->_cleanObjectDatas($object2clean);
}
}
}
return $object;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,332 @@
<?php
/*
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file ticketsup/class/ticketsuplogs.class.php
* \ingroup ticketsup
* \brief This file CRUD class file (Create/Read/Update/Delete) for ticket logs
*/
// Put here all includes required by your class file
require_once DOL_DOCUMENT_ROOT . "/core/class/commonobject.class.php";
//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
/**
* Put here description of your class
*/
class Ticketsuplogs// extends CommonObject
{
public $db; //!< To store db handler
public $error; //!< To return error code (or message)
public $errors = array(); //!< To return several error codes (or messages)
public $element = 'ticketsuplogs'; //!< Id that identify managed objects
public $table_element = 'ticketsuplogs'; //!< Name of table without prefix where object is stored
public $id;
public $fk_track_id;
public $fk_user_create;
public $datec = '';
public $message;
/**
* Constructor
*
* @param DoliDb $db Database handler
*/
public function __construct($db)
{
$this->db = $db;
return 1;
}
/**
* Create object into database
*
* @param User $user User that creates
* @param int $notrigger 0=launch triggers after, 1=disable triggers
* @return int <0 if KO, Id of created object if OK
*/
public function create($user, $notrigger = 0)
{
global $conf, $langs;
$error = 0;
// Clean parameters
if (isset($this->fk_track_id)) {
$this->fk_track_id = trim($this->fk_track_id);
}
if (isset($this->fk_user_create)) {
$this->fk_user_create = trim($this->fk_user_create);
}
if (isset($this->message)) {
$this->message = trim($this->message);
}
// Check parameters
// Put here code to add control on parameters values
// Insert request
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "ticketsup_logs(";
$sql .= "fk_track_id,";
$sql .= "fk_user_create,";
$sql .= "datec,";
$sql .= "message";
$sql .= ") VALUES (";
$sql .= " " . (!isset($this->fk_track_id) ? 'NULL' : "'" . $this->db->escape($this->fk_track_id) . "'") . ",";
$sql .= " " . (!isset($this->fk_user_create) ? 'NULL' : "'" . $this->fk_user_create . "'") . ",";
$sql .= " " . (!isset($this->datec) || dol_strlen($this->datec) == 0 ? 'NULL' : "'" . $this->db->idate($this->datec). "'") . ",";
$sql .= " " . (!isset($this->message) ? 'NULL' : "'" . $this->db->escape($this->message) . "'") . "";
$sql .= ")";
$this->db->begin();
dol_syslog(get_class($this) . "::create sql=" . $sql, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error " . $this->db->lasterror();
}
if (!$error) {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "ticketsup_logs");
if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
//// Call triggers
//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
//$interface=new Interfaces($this->db);
//$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
}
}
// Commit or rollback
if ($error) {
foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR);
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
}
$this->db->rollback();
return -1 * $error;
} else {
$this->db->commit();
return $this->id;
}
}
/**
* Load object in memory from the database
*
* @param int $id Id object
* @return int <0 if KO, >0 if OK
*/
public function fetch($id)
{
global $langs;
$sql = "SELECT";
$sql .= " t.rowid,";
$sql .= " t.fk_track_id,";
$sql .= " t.fk_user_create,";
$sql .= " t.datec,";
$sql .= " t.message";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup_logs as t";
$sql .= " WHERE t.rowid = " . $id;
dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
if ($this->db->num_rows($resql)) {
$obj = $this->db->fetch_object($resql);
$this->id = $obj->rowid;
$this->fk_track_id = $obj->fk_track_id;
$this->fk_user_create = $obj->fk_user_create;
$this->datec = $this->db->jdate($obj->datec);
$this->message = $obj->message;
}
$this->db->free($resql);
return 1;
} else {
$this->error = "Error " . $this->db->lasterror();
dol_syslog(get_class($this) . "::fetch " . $this->error, LOG_ERR);
return -1;
}
}
/**
* Update object into database
*
* @param User $user User that modifies
* @param int $notrigger 0=launch triggers after, 1=disable triggers
* @return int <0 if KO, >0 if OK
*/
public function update($user = 0, $notrigger = 0)
{
global $conf, $langs;
$error = 0;
// Clean parameters
if (isset($this->fk_track_id)) {
$this->fk_track_id = trim($this->fk_track_id);
}
if (isset($this->fk_user_create)) {
$this->fk_user_create = trim($this->fk_user_create);
}
if (isset($this->message)) {
$this->message = trim($this->message);
}
// Check parameters
// Put here code to add a control on parameters values
// Update request
$sql = "UPDATE " . MAIN_DB_PREFIX . "ticketsup_logs SET";
$sql .= " fk_track_id=" . (isset($this->fk_track_id) ? "'" . $this->db->escape($this->fk_track_id) . "'" : "null") . ",";
$sql .= " fk_user_create=" . (isset($this->fk_user_create) ? $this->fk_user_create : "null") . ",";
$sql .= " datec=" . (dol_strlen($this->datec) != 0 ? "'" . $this->db->idate($this->datec) . "'" : 'null') . ",";
$sql .= " message=" . (isset($this->message) ? "'" . $this->db->escape($this->message) . "'" : "null") . "";
$sql .= " WHERE rowid=" . $this->id;
$this->db->begin();
dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error " . $this->db->lasterror();
}
if (!$error) {
if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
//// Call triggers
//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
//$interface=new Interfaces($this->db);
//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
}
}
// Commit or rollback
if ($error) {
foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this) . "::update " . $errmsg, LOG_ERR);
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
}
$this->db->rollback();
return -1 * $error;
} else {
$this->db->commit();
return 1;
}
}
/**
* Delete object in database
*
* @param User $user User that deletes
* @param int $notrigger 0=launch triggers after, 1=disable triggers
* @return int <0 if KO, >0 if OK
*/
public function delete($user, $notrigger = 0)
{
global $conf, $langs;
$error = 0;
$this->db->begin();
if (!$error) {
if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
//// Call triggers
//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
//$interface=new Interfaces($this->db);
//$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
}
}
if (!$error) {
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "ticketsup_logs";
$sql .= " WHERE rowid=" . $this->id;
dol_syslog(get_class($this) . "::delete sql=" . $sql);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error " . $this->db->lasterror();
}
}
// Commit or rollback
if ($error) {
foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
}
$this->db->rollback();
return -1 * $error;
} else {
$this->db->commit();
return 1;
}
}
/**
* Initialise object with example values
* Id must be 0 if object instance is a specimen
*
* @return void
*/
public function initAsSpecimen()
{
$this->id = 0;
$this->fk_track_id = '';
$this->fk_user_create = '';
$this->datec = '';
$this->message = '';
}
}

View File

@ -0,0 +1,161 @@
<?php
/* Copyright (C) 2016 Jean-François Ferry <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file /ticketsup/class/ticketsupstats.class.php
* \ingroup ticketsup
* \brief Fichier de la classe de gestion des stats des tickets
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php';
require_once 'ticketsup.class.php';
/**
* \class DeplacementStats
* \brief Classe permettant la gestion des stats des deplacements et notes de frais
*/
class TicketsupStats extends Stats
{
public $table_element;
public $socid;
public $userid;
public $from;
public $field;
public $where;
/**
* Constructor
*
* @param DoliDB $db Database handler
* @param int $socid Id third party
* @param mixed $userid Id user for filter or array of user ids
* @return void
*/
public function __construct($db, $socid = 0, $userid = 0)
{
global $conf;
$this->db = $db;
$this->socid = $socid;
$this->userid = $userid;
$object = new Ticketsup($this->db);
$this->from = MAIN_DB_PREFIX . $object->table_element;
$this->field = 'km';
$this->where = " fk_statut > 0";
$this->where .= " AND entity = " . $conf->entity;
if ($this->socid) {
$this->where .= " AND fk_soc = " . $this->socid;
}
if (is_array($this->userid) && count($this->userid) > 0) {
$this->where .= ' AND fk_user IN (' . join(',', $this->userid) . ')';
} elseif ($this->userid > 0) {
$this->where .= ' AND fk_user = ' . $this->userid;
}
}
/**
* Renvoie le nombre de tickets par annee
*
* @return array Array of values
*/
public function getNbByYear()
{
$sql = "SELECT YEAR(datec) as dm, count(*)";
$sql .= " FROM " . $this->from;
$sql .= " GROUP BY dm DESC";
$sql .= " WHERE " . $this->where;
return $this->_getNbByYear($sql);
}
/**
* Renvoie le nombre de facture par mois pour une annee donnee
*
* @param string $year Year to scan
* @return array Array of values
*/
public function getNbByMonth($year)
{
$sql = "SELECT MONTH(datec) as dm, count(*)";
$sql .= " FROM " . $this->from;
$sql .= " WHERE YEAR(datec) = " . $year;
$sql .= " AND " . $this->where;
$sql .= " GROUP BY dm";
$sql .= $this->db->order('dm', 'DESC');
$res = $this->_getNbByMonth($year, $sql);
//var_dump($res);print '<br>';
return $res;
}
/**
* Renvoie le montant de facture par mois pour une annee donnee
*
* @param int $year Year to scan
* @return array Array of values
*/
public function getAmountByMonth($year)
{
$sql = "SELECT date_format(datec,'%m') as dm, sum(" . $this->field . ")";
$sql .= " FROM " . $this->from;
$sql .= " WHERE date_format(datec,'%Y') = '" . $year . "'";
$sql .= " AND " . $this->where;
$sql .= " GROUP BY dm";
$sql .= $this->db->order('dm', 'DESC');
$res = $this->_getAmountByMonth($year, $sql);
//var_dump($res);print '<br>';
return $res;
}
/**
* Return average amount
*
* @param int $year Year to scan
* @return array Array of values
*/
public function getAverageByMonth($year)
{
$sql = "SELECT date_format(datec,'%m') as dm, avg(" . $this->field . ")";
$sql .= " FROM " . $this->from;
$sql .= " WHERE date_format(datec,'%Y') = '" . $year . "'";
$sql .= " AND " . $this->where;
$sql .= " GROUP BY dm";
$sql .= $this->db->order('dm', 'DESC');
return $this->_getAverageByMonth($year, $sql);
}
/**
* Return nb, total and average
*
* @return array Array of values
*/
public function getAllByYear()
{
$sql = "SELECT date_format(datec,'%Y') as year, count(*) as nb, sum(" . $this->field . ") as total, avg(" . $this->field . ") as avg";
$sql .= " FROM " . $this->from;
$sql .= " WHERE " . $this->where;
$sql .= " GROUP BY year";
$sql .= $this->db->order('year', 'DESC');
return $this->_getAllByYear($sql);
}
}

View File

@ -0,0 +1,417 @@
<?php
/*
class.Diff.php
A class containing a diff implementation
Created by Stephen Morley - http://stephenmorley.org/ - and released under the
terms of the CC0 1.0 Universal legal code:
http://creativecommons.org/publicdomain/zero/1.0/legalcode
*/
// A class containing functions for computing diffs and formatting the output.
class Diff
{
// define the constants
const UNMODIFIED = 0;
const DELETED = 1;
const INSERTED = 2;
/* Returns the diff for two strings. The return value is an array, each of
* whose values is an array containing two values: a line (or character, if
* $compareCharacters is true), and one of the constants DIFF::UNMODIFIED (the
* line or character is in both strings), DIFF::DELETED (the line or character
* is only in the first string), and DIFF::INSERTED (the line or character is
* only in the second string). The parameters are:
*
* $string1 - the first string
* $string2 - the second string
* $compareCharacters - true to compare characters, and false to compare
* lines; this optional parameter defaults to false
*/
public static function compare(
$string1,
$string2,
$compareCharacters = false
) {
// initialise the sequences and comparison start and end positions
$start = 0;
if ($compareCharacters) {
$sequence1 = $string1;
$sequence2 = $string2;
$end1 = strlen($string1) - 1;
$end2 = strlen($string2) - 1;
} else {
$sequence1 = preg_split('/\R/', $string1);
$sequence2 = preg_split('/\R/', $string2);
$end1 = count($sequence1) - 1;
$end2 = count($sequence2) - 1;
}
// skip any common prefix
while ($start <= $end1 && $start <= $end2
&& $sequence1[$start] == $sequence2[$start]) {
$start++;
}
// skip any common suffix
while ($end1 >= $start && $end2 >= $start
&& $sequence1[$end1] == $sequence2[$end2]) {
$end1--;
$end2--;
}
// compute the table of longest common subsequence lengths
$table = self::computeTable($sequence1, $sequence2, $start, $end1, $end2);
// generate the partial diff
$partialDiff =
self::generatePartialDiff($table, $sequence1, $sequence2, $start);
// generate the full diff
$diff = array();
for ($index = 0; $index < $start; $index++) {
$diff[] = array($sequence1[$index], self::UNMODIFIED);
}
while (count($partialDiff) > 0) {
$diff[] = array_pop($partialDiff);
}
for ($index = $end1 + 1;
$index < ($compareCharacters ? strlen($sequence1) : count($sequence1));
$index++) {
$diff[] = array($sequence1[$index], self::UNMODIFIED);
}
// return the diff
return $diff;
}
/* Returns the diff for two files. The parameters are:
*
* $file1 - the path to the first file
* $file2 - the path to the second file
* $compareCharacters - true to compare characters, and false to compare
* lines; this optional parameter defaults to false
*/
public static function compareFiles(
$file1,
$file2,
$compareCharacters = false
) {
// return the diff of the files
return self::compare(
file_get_contents($file1),
file_get_contents($file2),
$compareCharacters
);
}
/* Returns the table of longest common subsequence lengths for the specified
* sequences. The parameters are:
*
* $sequence1 - the first sequence
* $sequence2 - the second sequence
* $start - the starting index
* $end1 - the ending index for the first sequence
* $end2 - the ending index for the second sequence
*/
private static function computeTable(
$sequence1,
$sequence2,
$start,
$end1,
$end2
) {
// determine the lengths to be compared
$length1 = $end1 - $start + 1;
$length2 = $end2 - $start + 1;
// initialise the table
$table = array(array_fill(0, $length2 + 1, 0));
// loop over the rows
for ($index1 = 1; $index1 <= $length1; $index1++) {
// create the new row
$table[$index1] = array(0);
// loop over the columns
for ($index2 = 1; $index2 <= $length2; $index2++) {
// store the longest common subsequence length
if ($sequence1[$index1 + $start - 1]== $sequence2[$index2 + $start - 1]
) {
$table[$index1][$index2] = $table[$index1 - 1][$index2 - 1] + 1;
} else {
$table[$index1][$index2] =
max($table[$index1 - 1][$index2], $table[$index1][$index2 - 1]);
}
}
}
// return the table
return $table;
}
/* Returns the partial diff for the specificed sequences, in reverse order.
* The parameters are:
*
* $table - the table returned by the computeTable function
* $sequence1 - the first sequence
* $sequence2 - the second sequence
* $start - the starting index
*/
private static function generatePartialDiff(
$table,
$sequence1,
$sequence2,
$start
) {
// initialise the diff
$diff = array();
// initialise the indices
$index1 = count($table) - 1;
$index2 = count($table[0]) - 1;
// loop until there are no items remaining in either sequence
while ($index1 > 0 || $index2 > 0) {
// check what has happened to the items at these indices
if ($index1 > 0 && $index2 > 0
&& $sequence1[$index1 + $start - 1]== $sequence2[$index2 + $start - 1]
) {
// update the diff and the indices
$diff[] = array($sequence1[$index1 + $start - 1], self::UNMODIFIED);
$index1--;
$index2--;
} elseif ($index2 > 0
&& $table[$index1][$index2] == $table[$index1][$index2 - 1]
) {
// update the diff and the indices
$diff[] = array($sequence2[$index2 + $start - 1], self::INSERTED);
$index2--;
} else {
// update the diff and the indices
$diff[] = array($sequence1[$index1 + $start - 1], self::DELETED);
$index1--;
}
}
// return the diff
return $diff;
}
/* Returns a diff as a string, where unmodified lines are prefixed by ' ',
* deletions are prefixed by '- ', and insertions are prefixed by '+ '. The
* parameters are:
*
* $diff - the diff array
* $separator - the separator between lines; this optional parameter defaults
* to "\n"
*/
public static function toString($diff, $separator = "\n")
{
// initialise the string
$string = '';
// loop over the lines in the diff
foreach ($diff as $line) {
// extend the string with the line
switch ($line[1]) {
case self::UNMODIFIED:
$string .= ' ' . $line[0];
break;
case self::DELETED:
$string .= '- ' . $line[0];
break;
case self::INSERTED:
$string .= '+ ' . $line[0];
break;
}
// extend the string with the separator
$string .= $separator;
}
// return the string
return $string;
}
/* Returns a diff as an HTML string, where unmodified lines are contained
* within 'span' elements, deletions are contained within 'del' elements, and
* insertions are contained within 'ins' elements. The parameters are:
*
* $diff - the diff array
* $separator - the separator between lines; this optional parameter defaults
* to '<br>'
*/
public static function toHTML($diff, $separator = '<br>')
{
// initialise the HTML
$html = '';
// loop over the lines in the diff
foreach ($diff as $line) {
// extend the HTML with the line
switch ($line[1]) {
case self::UNMODIFIED:
$element = 'span';
break;
case self::DELETED:
$element = 'del';
break;
case self::INSERTED:
$element = 'ins';
break;
}
$html .=
'<' . $element . '>'
. htmlspecialchars($line[0])
. '</' . $element . '>';
// extend the HTML with the separator
$html .= $separator;
}
// return the HTML
return $html;
}
/* Returns a diff as an HTML table. The parameters are:
*
* $diff - the diff array
* $indentation - indentation to add to every line of the generated HTML; this
* optional parameter defaults to ''
* $separator - the separator between lines; this optional parameter
* defaults to '<br>'
*/
public static function toTable($diff, $indentation = '', $separator = '<br>')
{
// initialise the HTML
$html = $indentation . "<table class=\"diff\">\n";
// loop over the lines in the diff
$index = 0;
while ($index < count($diff)) {
// determine the line type
switch ($diff[$index][1]) {
// display the content on the left and right
case self::UNMODIFIED:
$leftCell =
self::getCellContent(
$diff,
$indentation,
$separator,
$index,
self::UNMODIFIED
);
$rightCell = $leftCell;
break;
// display the deleted on the left and inserted content on the right
case self::DELETED:
$leftCell =
self::getCellContent(
$diff,
$indentation,
$separator,
$index,
self::DELETED
);
$rightCell =
self::getCellContent(
$diff,
$indentation,
$separator,
$index,
self::INSERTED
);
break;
// display the inserted content on the right
case self::INSERTED:
$leftCell = '';
$rightCell =
self::getCellContent(
$diff,
$indentation,
$separator,
$index,
self::INSERTED
);
break;
}
// extend the HTML with the new row
$html .=
$indentation
. " <tr>\n"
. $indentation
. ' <td class="diff'
. ($leftCell == $rightCell
? 'Unmodified'
: ($leftCell == '' ? 'Blank' : 'Deleted'))
. '">'
. $leftCell
. "</td>\n"
. $indentation
. ' <td class="diff'
. ($leftCell == $rightCell
? 'Unmodified'
: ($rightCell == '' ? 'Blank' : 'Inserted'))
. '">'
. $rightCell
. "</td>\n"
. $indentation
. " </tr>\n";
}
// return the HTML
return $html . $indentation . "</table>\n";
}
/* Returns the content of the cell, for use in the toTable function. The
* parameters are:
*
* $diff - the diff array
* $indentation - indentation to add to every line of the generated HTML
* $separator - the separator between lines
* $index - the current index, passes by reference
* $type - the type of line
*/
private static function getCellContent(
$diff,
$indentation,
$separator,
&$index,
$type
) {
// initialise the HTML
$html = '';
// loop over the matching lines, adding them to the HTML
while ($index < count($diff) && $diff[$index][1] == $type) {
$html .=
'<span>'
. htmlspecialchars($diff[$index][0])
. '</span>'
. $separator;
$index++;
}
// return the HTML
return $html;
}
}

View File

@ -0,0 +1,186 @@
<?php
/* Copyright (C) 2011-2016 Jean-François Ferry <hello@librethic.io>
* Copyright (C) 2011 Regis Houssin <regis@dolibarr.fr>
* 2016 Christophe Battarel <christophe@altairis.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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* \file ticketsup/contacts.php
* \ingroup ticketsup
* \brief Contacts des tickets
*/
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once 'class/ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT . "/core/lib/company.lib.php";
require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("ticketsup@ticketsup");
// Get parameters
$socid = GETPOST("socid", 'int');
$action = GETPOST("action", 'alpha');
$track_id = GETPOST("track_id", 'alpha');
$id = GETPOST("id", 'int');
$ref = GETPOST('ref', 'alpha');
$type = GETPOST('type', 'alpha');
$source = GETPOST('source', 'alpha');
$ligne = GETPOST('ligne', 'int');
$lineid = GETPOST('lineid', 'int');
// Protection if external user
if ($user->societe_id > 0) {
$socid = $user->societe_id;
accessforbidden();
}
// Store current page url
$url_page_current = dol_buildpath('/ticketsup/contacts.php', 1);
$object = new Ticketsup($db);
/*
* Ajout d'un nouveau contact
*/
if ($action == 'addcontact' && $user->rights->ticketsup->write) {
$result = $object->fetch($id, $track_id);
if ($result > 0 && ($id > 0 || (!empty($track_id)))) {
$contactid = (GETPOST('userid', 'int') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int'));
$result = $object->add_contact($contactid, $type, $source);
}
if ($result >= 0) {
Header("Location: " . $url_page_current . "?id=" . $object->id);
exit;
} else {
if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
$langs->load("errors");
setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
}
}
// bascule du statut d'un contact
if ($action == 'swapstatut' && $user->rights->ticketsup->write) {
if ($object->fetch($id, $track_id)) {
$result = $object->swapContactStatus($ligne);
} else {
dol_print_error($db, $object->error);
}
}
// Efface un contact
if ($action == 'deletecontact' && $user->rights->ticketsup->write) {
if ($object->fetch($id, $track_id)) {
$result = $object->delete_contact($lineid);
if ($result >= 0) {
Header("Location: " . $url_page_current . "?id=" . $object->id);
exit;
}
}
}
/*
* View
*/
$help_url = 'FR:DocumentationModuleTicket';
llxHeader('', $langs->trans("TicketContacts"), $help_url);
$form = new Form($db);
$formcompany = new FormCompany($db);
$contactstatic = new Contact($db);
$userstatic = new User($db);
/* *************************************************************************** */
/* */
/* Mode vue et edition */
/* */
/* *************************************************************************** */
if ($id > 0 || !empty($track_id) || !empty($ref)) {
if ($object->fetch($id, $track_id, $ref) > 0) {
if ($object->fk_soc > 0) {
$object->fetch_thirdparty();
$head = societe_prepare_head($object->thirdparty);
dol_fiche_head($head, 'ticketsup', $langs->trans("ThirdParty"), 0, 'company');
dol_banner_tab($object->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
dol_fiche_end();
}
if (!$user->societe_id && $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY) {
$object->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'";
} elseif ($user->societe_id > 0) {
$object->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'";
}
$head = ticketsup_prepare_head($object);
dol_fiche_head($head, 'tabTicketContacts', $langs->trans("Ticket"), 0, 'ticketsup@ticketsup');
$object->label = $object->ref;
// Author
if ($object->fk_user_create > 0) {
$object->label .= ' - ' . $langs->trans("CreatedBy") . ' ';
$langs->load("users");
$fuser = new User($db);
$fuser->fetch($object->fk_user_create);
$object->label .= $fuser->getNomUrl(0);
}
$linkback = '<a href="' . dol_buildpath('/ticketsup/list.php', 1) . '"><strong>' . $langs->trans("BackToList") . '</strong></a> ';
$object->ticketsup_banner_tab('ref', '', ($user->societe_id ? 0 : 1), 'ref', 'subject', '', '', '', $morehtmlleft, $linkback);
dol_fiche_end();
print '<br>';
$permission = $user->rights->ticketsup->write;
// Contacts lines (modules that overwrite templates must declare this into descriptor)
$dirtpls=array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
foreach ($dirtpls as $reldir) {
$res=@include dol_buildpath($reldir.'/contacts.tpl.php');
if ($res) {
break;
}
}
} else {
print "ErrorRecordNotFound";
}
}
// End of page
llxFooter();
$db->close();

57
htdocs/ticketsup/css/bg.css.php Executable file
View File

@ -0,0 +1,57 @@
<?php
//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled because need to load personalized language
//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled to increase speed. Language code is found on url.
if (! defined('NOREQUIRESOC')) {
define('NOREQUIRESOC', '1');
}
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled because need to do translations
if (! defined('NOCSRFCHECK')) {
define('NOCSRFCHECK', 1);
}
if (! defined('NOTOKENRENEWAL')) {
define('NOTOKENRENEWAL', 1);
}
if (! defined('NOLOGIN')) {
define('NOLOGIN', 1); // File must be accessed by logon page so without login
}if (! defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', 1);
}
if (! defined('NOREQUIREHTML')) {
define('NOREQUIREHTML', 1);
}
if (! defined('NOREQUIREAJAX')) {
define('NOREQUIREAJAX', '1');
}
session_cache_limiter(false);
require_once '../../../main.inc.php';
// Load user to have $user->conf loaded (not done into main because of NOLOGIN constant defined)
if (empty($user->id) && ! empty($_SESSION['dol_login'])) {
$user->fetch('', $_SESSION['dol_login']);
}
// Define css type
header('Content-type: text/css');
// Important: Following code is to avoid page request by browser and PHP CPU at
// each Dolibarr page access.
if (empty($dolibarr_nocache)) {
header('Cache-Control: max-age=3600, public, must-revalidate');
} else {
header('Cache-Control: no-cache');
}
// On the fly GZIP compression for all pages (if browser support it). Must set the bit 3 of constant to 1.
if (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x04)) {
ob_start("ob_gzhandler");
}
print 'html {';
if (! empty($conf->global->TICKETS_SHOW_MODULE_LOGO)) {
print 'background: url("../public/img/bg_ticket.png") no-repeat 95% 90%;';
}
print '}';

View File

@ -0,0 +1,115 @@
html {
min-height: 100%; height: 100%;
}
body {
font-size: 0.88em;
background: none;
min-height: 600px;
/*padding-bottom:150px;*/
}
div.corps {
font-family: arial;
position: static;
padding: 2em 1em;
overflow-x: auto;
border: 2px solid rgb(153, 153, 153);
background-color: rgb(255, 255, 255);
box-shadow: 2px 2px 2px rgb(245, 245, 245);
border-radius: 10px 10px 10px 10px;
margin: 1.5em;
background : #ffffff;
}
.index_create, .index_display {
float: left;
width: 33%;
text-align: center;
}
.orange {
color: #fef4e9;
border: solid 1px #da7c0c;
background: #f78d1d;
background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20));
background: -moz-linear-gradient(top, #faa51a, #f47a20);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#faa51a', endColorstr='#f47a20');
}
.orange:active {
color: #fcd3a5;
background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a));
background: -moz-linear-gradient(top, #f47a20, #faa51a);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f47a20', endColorstr='#faa51a');
}
.orange:hover {
background: #f47c20;
background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015));
background: -moz-linear-gradient(top, #f88e11, #f06015);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f88e11', endColorstr='#f06015');
}
.blue {
color: #d9eef7;
border: solid 1px #0076a3;
background: #0095cd;
background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));
background: -moz-linear-gradient(top, #00adee, #0078a5);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5');
}
.blue:active {
color: #80bed6;
background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));
background: -moz-linear-gradient(top, #0078a5, #00adee);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee');
}
.blue:hover {
background: #007ead;
background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));
background: -moz-linear-gradient(top, #0095cc, #00678e);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e');
}
#form_create_ticket,
#form_view_ticket {
margin-left: 10px;
margin-right: 10px;
padding-left:1em;
padding-right:1em;
padding-top:1.5em;
padding-bottom:12px;
border: 1px solid #C0C0C0;
background-color: #E0E0E0;
-moz-box-shadow: 4px 4px 4px #DDD;
-webkit-box-shadow: 4px 4px 4px #DDD;
box-shadow: 4px 4px 4px #DDD;
border-radius: 8px;
border:solid 1px rgba(168,168,168,.4);
border-top:solid 1px f8f8f8;
background-color: #f8f8f8;
background-image: -o-linear-gradient(top, rgba(250,250,250,.6) 0%, rgba(192,192,192,.3) 100%);
background-image: -moz-linear-gradient(top, rgba(250,250,250,.6) 0%, rgba(192,192,192,.3) 100%);
background-image: -webkit-linear-gradient(top, rgba(250,250,250,.6) 0%, rgba(192,192,192,.3) 100%);
background-image: -ms-linear-gradient(top, rgba(250,250,250,.6) 0%, rgba(192,192,192,.3) 100%);
background-image: linear-gradient(top, rgba(250,250,250,.6) 0%, rgba(192,192,192,.3) 100%);
}
#form_create_ticket input.text,
#form_create_ticket textarea { width:450px;}
div.info {
background: none repeat scroll 0% 0% rgb(252, 245, 184);
padding: 2px 4px 2px 6px;
margin: 1.5em 1em;
border: 1px solid rgb(188, 169, 54);
font-weight: normal;
}
div.warning { color: #333333;}

View File

@ -0,0 +1,265 @@
#cd-timeline {
position: relative;
padding: 2em 0;
margin-bottom: 2em;
}
#cd-timeline::before {
/* this is the vertical line */
content: '';
position: absolute;
top: 0;
left: 18px;
height: 100%;
width: 4px;
background: #d7e4ed;
}
@media only screen and (min-width: 1170px) {
#cd-timeline {
margin-bottom: 3em;
}
#cd-timeline::before {
left: 50%;
margin-left: -2px;
}
}
.cd-timeline-block {
position: relative;
margin: 2em 0;
}
.cd-timeline-block:after {
content: "";
display: table;
clear: both;
}
.cd-timeline-block:first-child {
margin-top: 0;
}
.cd-timeline-block:last-child {
margin-bottom: 0;
}
@media only screen and (min-width: 1170px) {
.cd-timeline-block {
margin: 4em 0;
}
.cd-timeline-block:first-child {
margin-top: 0;
}
.cd-timeline-block:last-child {
margin-bottom: 0;
}
}
.cd-timeline-img {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
border-radius: 50%;
box-shadow: 0 0 0 4px white, inset 0 2px 0 rgba(0, 0, 0, 0.08), 0 3px 0 4px rgba(0, 0, 0, 0.05);
background: #d7e4ed;
}
.cd-timeline-img img {
display: block;
width: 24px;
height: 24px;
position: relative;
left: 50%;
top: 50%;
margin-left: -12px;
margin-top: -12px;
}
.cd-timeline-img.cd-picture {
background: #75ce66;
}
.cd-timeline-img.cd-movie {
background: #c03b44;
}
.cd-timeline-img.cd-location {
background: #f0ca45;
}
@media only screen and (min-width: 1170px) {
.cd-timeline-img {
width: 60px;
height: 60px;
left: 50%;
margin-left: -30px;
/* Force Hardware Acceleration in WebKit */
-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;
}
.cssanimations .cd-timeline-img.is-hidden {
visibility: hidden;
}
.cssanimations .cd-timeline-img.bounce-in {
visibility: visible;
-webkit-animation: cd-bounce-1 0.6s;
-moz-animation: cd-bounce-1 0.6s;
animation: cd-bounce-1 0.6s;
}
}
@-webkit-keyframes cd-bounce-1 {
0% {
opacity: 0;
-webkit-transform: scale(0.5);
}
60% {
opacity: 1;
-webkit-transform: scale(1.2);
}
100% {
-webkit-transform: scale(1);
}
}
@-moz-keyframes cd-bounce-1 {
0% {
opacity: 0;
-moz-transform: scale(0.5);
}
60% {
opacity: 1;
-moz-transform: scale(1.2);
}
100% {
-moz-transform: scale(1);
}
}
@keyframes cd-bounce-1 {
0% {
opacity: 0;
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
-ms-transform: scale(0.5);
-o-transform: scale(0.5);
transform: scale(0.5);
}
60% {
opacity: 1;
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
-ms-transform: scale(1.2);
-o-transform: scale(1.2);
transform: scale(1.2);
}
100% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
.cd-timeline-content {
position: relative;
margin-left: 60px;
background: white;
border-radius: 0.25em;
padding: 1em;
background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(230,230,230,0.4) 100%);
background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(230,230,230,0.4) 100%);
background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(230,230,230,0.4) 100%);
background-image: -ms-linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(230,230,230,0.4) 100%);
background-image: linear-gradient(bottom, rgba(0,0,0,0.1) 0%, rgba(230,230,230,0.4) 100%);
}
.cd-timeline-content:after {
content: "";
display: table;
clear: both;
}
.cd-timeline-content h2 {
color: #303e49;
}
.cd-timeline-content .cd-date {
font-size: 13px;
font-size: 0.8125rem;
}
.cd-timeline-content .cd-date {
display: inline-block;
}
.cd-timeline-content p {
margin: 1em 0;
line-height: 1.6;
}
.cd-timeline-content .cd-date {
float: left;
padding: .2em 0;
opacity: .7;
}
.cd-timeline-content::before {
content: '';
position: absolute;
top: 16px;
right: 100%;
height: 0;
width: 0;
border: 7px solid transparent;
border-right: 7px solid white;
}
@media only screen and (min-width: 768px) {
.cd-timeline-content h2 {
font-size: 20px;
font-size: 1.25rem;
}
.cd-timeline-content {
font-size: 16px;
font-size: 1rem;
}
.cd-timeline-content .cd-read-more, .cd-timeline-content .cd-date {
font-size: 14px;
font-size: 0.875rem;
}
}
@media only screen and (min-width: 1170px) {
.cd-timeline-content {
margin-left: 0;
padding: 1.6em;
width: 43%;
}
.cd-timeline-content::before {
top: 24px;
left: 100%;
border-color: transparent;
border-left-color: white;
}
.cd-timeline-content .cd-read-more {
float: left;
}
.cd-timeline-content .cd-date {
position: absolute;
width: 55%;
left: 115%;
top: 6px;
font-size: 16px;
font-size: 1rem;
}
.cd-timeline-block:nth-child(even) .cd-timeline-content {
float: right;
}
.cd-timeline-block:nth-child(even) .cd-timeline-content::before {
top: 24px;
left: auto;
right: 100%;
border-color: transparent;
border-right-color: white;
}
.cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more {
float: right;
}
.cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date {
left: auto;
right: 115%;
text-align: right;
}
}

View File

@ -0,0 +1,168 @@
<?php
/*
* Copyright (C) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2010 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013-2016 Jean-François Ferry <hello@librethic.io>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file /ticketsup/document.php
* \ingroup ticketsup
* \brief files linked to a ticket
*/
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
require_once 'class/ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/images.lib.php';
require_once DOL_DOCUMENT_ROOT . "/core/lib/company.lib.php";
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
$langs->load("companies");
$langs->load('other');
$action = GETPOST('action');
$confirm = GETPOST('confirm');
$id = GETPOST('id', 'int');
$track_id = GETPOST('track_id', 'alpha');
$ref = GETPOST('ref', 'alpha');
// Security check
if (!$user->rights->ticketsup->read) {
accessforbidden();
}
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
$page = GETPOST("page", 'int');
if ($page == -1) {
$page = 0;
}
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (!$sortorder) {
$sortorder = "ASC";
}
if (!$sortfield) {
$sortfield = "name";
}
$object = new Ticketsup($db);
$result = $object->fetch($id, $track_id, $ref);
// to match document rules and compatibility
$old_ref = $object->ref;
$object->ref = $object->track_id;
if ($result < 0) {
setEventMessage($object->error, 'errors');
} else {
$upload_dir = $conf->ticketsup->dir_output . "/" . dol_sanitizeFileName($object->track_id);
}
/*
* Actions
*/
// Included file moved into Dolibarr 4, keep it for compatibility
$res=@include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
if (! $res) {
include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php';
}
$object->ref = $old_ref;
/*
* View
*/
$form = new Form($db);
$help_url = '';
llxHeader('', $langs->trans("TicketDocumentsLinked") . ' - ' . $langs->trans("Files"), $help_url);
if ($object->id) {
/*
* Affichage onglets
*/
if (!empty($conf->notification->enabled)) {
$langs->load("mails");
}
$form = new Form($db);
if ($object->fk_soc > 0) {
$object->fetch_thirdparty();
$head = societe_prepare_head($object->thirdparty);
dol_fiche_head($head, 'ticketsup', $langs->trans("ThirdParty"), 0, 'company');
dol_banner_tab($object->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
dol_fiche_end();
}
if (!$user->societe_id && $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY) {
$object->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'";
} elseif ($user->societe_id > 0) {
$object->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'";
}
$head = ticketsup_prepare_head($object);
dol_fiche_head($head, 'tabTicketDocument', $langs->trans("Ticket"), 0, 'ticketsup@ticketsup');
$object->label = $object->ref;
// Author
if ($object->fk_user_create > 0) {
$object->label .= ' - ' . $langs->trans("CreatedBy") . ' ';
$langs->load("users");
$fuser = new User($db);
$fuser->fetch($object->fk_user_create);
$object->label .= $fuser->getNomUrl(0);
}
$linkback = '<a href="' . dol_buildpath('/ticketsup/list.php', 1) . '"><strong>' . $langs->trans("BackToList") . '</strong></a> ';
$object->ticketsup_banner_tab('ref', '', ($user->societe_id ? 0 : 1), 'ref', 'subject', '', '', '', $morehtmlleft, $linkback);
dol_fiche_end();
// Construit liste des fichiers
$filearray = dol_dir_list($upload_dir, "files", 0, '', '\.meta$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
$totalsize = 0;
foreach ($filearray as $key => $file) {
$totalsize += $file['size'];
}
// For compatibility we use track ID for directory
$object->ref = $object->track_id;
$modulepart = 'ticketsup';
$permission = $user->rights->ticketsup->write;
include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
print "<br><br>";
} else {
accessforbidden('', 0, 0);
}
llxFooter();
$db->close();

View File

@ -0,0 +1,139 @@
<?php
/*
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* History of ticket
*
* @package ticketsup
*/
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once 'class/actions_ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
require_once DOL_DOCUMENT_ROOT . "/core/lib/company.lib.php";
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
if (!class_exists('Contact')) {
include DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
}
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
// Get parameters
$id = GETPOST('id', 'int');
$track_id = GETPOST('track_id', 'alpha', 3);
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'alpha', 3);
// Security check
if (!$user->rights->ticketsup->read) {
accessforbidden();
}
$object = new ActionsTicketsup($db);
$object->doActions($action);
$extrafields = new ExtraFields($db);
$extralabels = $extrafields->fetch_name_optionals_label($object->dao->table_element);
if (!$action) {
$action = 'view';
}
/***************************************************
* PAGE
*
* Put here all code to build page
****************************************************/
$help_url = 'FR:DocumentationModuleTicket';
$page_title = $object->getTitle($action);
llxHeader('', $page_title, $help_url);
$userstat = new User($db);
$form = new Form($db);
$formticket = new FormTicketsup($db);
if ($action == 'view') {
$res = $object->fetch($id, $track_id, $ref);
if ($res > 0) {
// restrict access for externals users
if ($user->societe_id > 0 && ($object->dao->fk_soc != $user->societe_id)
) {
accessforbidden('', 0);
}
// or for unauthorized internals users
if (!$user->societe_id && ($conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY && $object->dao->fk_user_assign != $user->id) && !$user->rights->ticketsup->manage) {
accessforbidden('', 0);
}
if ($object->dao->fk_soc > 0) {
$object->dao->fetch_thirdparty();
$head = societe_prepare_head($object->dao->thirdparty);
dol_fiche_head($head, 'ticketsup', $langs->trans("ThirdParty"), 0, 'company');
dol_banner_tab($object->dao->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
dol_fiche_end();
}
if (!$user->societe_id && $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY) {
$object->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'";
} elseif ($user->societe_id > 0) {
$object->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'";
}
$head = ticketsup_prepare_head($object->dao);
dol_fiche_head($head, 'tabTicketLogs', $langs->trans("Ticket"), 0, 'ticketsup@ticketsup');
$object->dao->label = $object->dao->ref;
// Author
if ($object->dao->fk_user_create > 0) {
$object->dao->label .= ' - ' . $langs->trans("CreatedBy") . ' ';
$langs->load("users");
$fuser = new User($db);
$fuser->fetch($object->dao->fk_user_create);
$object->dao->label .= $fuser->getNomUrl(0);
}
$linkback = '<a href="' . dol_buildpath('/ticketsup/list.php', 1) . '"><strong>' . $langs->trans("BackToList") . '</strong></a> ';
$object->dao->ticketsup_banner_tab('ref', '', ($user->societe_id ? 0 : 1), 'ref', 'subject', '', '', '', $morehtmlleft, $linkback);
dol_fiche_end();
print '<div class="fichecenter">';
// Logs list
print load_fiche_titre($langs->trans('TicketHistory'), '', 'history@ticketsup');
$object->viewTimelineTicketLogs();
print '</div><!-- fichecenter -->';
print '<br style="clear: both">';
}
} // End action view
// End of page
llxFooter('');
$db->close();

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

377
htdocs/ticketsup/index.php Normal file
View File

@ -0,0 +1,377 @@
<?php
/**
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
*
* 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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* Index page for ticket module
*
* @package ticketsup
*/
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once 'class/actions_ticketsup.class.php';
require_once 'class/ticketsupstats.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/dolgraph.class.php';
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
$WIDTH = DolGraph::getDefaultGraphSizeForStats('width');
$HEIGHT = DolGraph::getDefaultGraphSizeForStats('height');
// Get parameters
$id = GETPOST('id', 'int');
$msg_id = GETPOST('msg_id', 'int');
$action = GETPOST('action', 'alpha', 3);
if ($user->societe_id) {
$socid = $user->societe_id;
}
// Security check
$result = restrictedArea($user, 'ticketsup', 0, '', '', '', '');
$nowyear = strftime("%Y", dol_now());
$year = GETPOST('year') > 0 ? GETPOST('year') : $nowyear;
//$startyear=$year-2;
$startyear = $year - 1;
$endyear = $year;
$object = new ActionsTicketsup($db);
/*******************************************************************
* ACTIONS
*
* Put here all code to do according to value of "action" parameter
********************************************************************/
/***************************************************
* PAGE
*
* Put here all code to build page
****************************************************/
llxHeader('', $langs->trans('TicketsIndex'), '');
$form = new Form($db);
$dir = '';
$filenamenb = $dir . "/" . $prefix . "ticketsupinyear-" . $endyear . ".png";
$fileurlnb = DOL_URL_ROOT . '/viewimage.php?modulepart=ticketsup&amp;file=ticketsupinyear-' . $endyear . '.png';
$stats = new TicketsupStats($db, $socid, $userid);
$param_year = 'DOLUSERCOOKIE_ticketsup_by_status_year';
$param_shownb = 'DOLUSERCOOKIE_ticketsup_by_status_shownb';
$param_showtot = 'DOLUSERCOOKIE_ticketsup_by_status_showtot';
$autosetarray = preg_split("/[,;:]+/", GETPOST('DOL_AUTOSET_COOKIE'));
if (in_array('DOLUSERCOOKIE_ticketsup_by_status', $autosetarray)) {
$endyear = GETPOST($param_year, 'int');
$shownb = GETPOST($param_shownb, 'alpha');
$showtot = GETPOST($param_showtot, 'alpha');
} else {
$tmparray = json_decode($_COOKIE['DOLUSERCOOKIE_ticketsup_by_status'], true);
$endyear = $tmparray['year'];
$shownb = $tmparray['shownb'];
$showtot = $tmparray['showtot'];
}
if (empty($shownb) && empty($showtot)) {
$showtot = 1;
}
$nowarray = dol_getdate(dol_now(), true);
if (empty($endyear)) {
$endyear = $nowarray['year'];
}
$startyear = $endyear - 1;
$WIDTH = (($shownb && $showtot) || !empty($conf->dol_optimize_smallscreen)) ? '256' : '320';
$HEIGHT = '192';
print '<div class="fichecenter"><div class="fichethirdleft">';
/*
* Statistics area
*/
$tick = array(
'unread' => 0,
'read' => 0,
'answered' => 0,
'assigned' => 0,
'inprogress' => 0,
'waiting' => 0,
'closed' => 0,
'deleted' => 0,
);
$total = 0;
$sql = "SELECT t.fk_statut, COUNT(t.fk_statut) as nb";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup as t";
if (!$user->rights->societe->client->voir && !$socid) {
$sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
}
$sql .= ' WHERE t.entity IN (' . getEntity('ticketsup', 1) . ')';
$sql .= " AND t.fk_statut IS NOT NULL";
$sql .= " AND date_format(datec,'%Y') = '" . $endyear . "'";
if (!$user->rights->societe->client->voir && !$socid) {
$sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = " . $user->id;
}
// External users restriction
if ($user->societe_id > 0) {
$sql .= " AND t.fk_soc='" . $user->societe_id . "'";
} else {
// For internals users,
if (!empty($conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY) && !$user->rights->ticketsup->manage) {
$sql .= " AND t.fk_user_assign=" . $user->id;
}
}
$sql .= " GROUP BY t.fk_statut";
$result = $db->query($sql);
if ($result) {
while ($objp = $db->fetch_object($result)) {
$found = 0;
if ($objp->fk_statut == 0) {
$tick['unread'] = $objp->nb;
}
if ($objp->fk_statut == 1) {
$tick['read'] = $objp->nb;
}
if ($objp->fk_statut == 3) {
$tick['answered'] = $objp->nb;
}
if ($objp->fk_statut == 4) {
$tick['assigned'] = $objp->nb;
}
if ($objp->fk_statut == 5) {
$tick['inprogress'] = $objp->nb;
}
if ($objp->fk_statut == 6) {
$tick['waiting'] = $objp->nb;
}
if ($objp->fk_statut == 8) {
$tick['closed'] = $objp->nb;
}
if ($objp->fk_statut == 9) {
$tick['deleted'] = $objp->nb;
}
}
if ((round($tick['unread']) ? 1 : 0) +(round($tick['read']) ? 1 : 0) +(round($tick['answered']) ? 1 : 0) +(round($tick['assigned']) ? 1 : 0) +(round($tick['inprogress']) ? 1 : 0) +(round($tick['waiting']) ? 1 : 0) +(round($tick['closed']) ? 1 : 0) +(round($tick['deleted']) ? 1 : 0) >= 2
) {
$dataseries = array();
$dataseries[] = array('label' => $langs->trans("NotRead"), 'data' => round($tick['unread']));
$dataseries[] = array('label' => $langs->trans("Read"), 'data' => round($tick['read']));
$dataseries[] = array('label' => $langs->trans("Answered"), 'data' => round($tick['answered']));
$dataseries[] = array('label' => $langs->trans("Assigned"), 'data' => round($tick['assigned']));
$dataseries[] = array('label' => $langs->trans("InProgress"), 'data' => round($tick['inprogress']));
$dataseries[] = array('label' => $langs->trans("Waiting"), 'data' => round($tick['waiting']));
$dataseries[] = array('label' => $langs->trans("Closed"), 'data' => round($tick['Closed']));
$dataseries[] = array('label' => $langs->trans("Deleted"), 'data' => round($tick['Deleted']));
}
} else {
dol_print_error($db);
}
$stringtoshow = '';
$stringtoshow .= '<script type="text/javascript" language="javascript">
jQuery(document).ready(function() {
jQuery("#idsubimgDOLUSERCOOKIE_ticketsup_by_status").click(function() {
jQuery("#idfilterDOLUSERCOOKIE_ticketsup_by_status").toggle();
});
});
</script>';
$stringtoshow .= '<div class="center hideobject" id="idfilterDOLUSERCOOKIE_ticketsup_by_status">'; // hideobject is to start hidden
$stringtoshow .= '<form class="flat formboxfilter" method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
$stringtoshow .= '<input type="hidden" name="action" value="' . $refreshaction . '">';
$stringtoshow .= '<input type="hidden" name="DOL_AUTOSET_COOKIE" value="DOLUSERCOOKIE_ticketsup_by_status:year,shownb,showtot">';
$stringtoshow .= $langs->trans("Year") . ' <input class="flat" size="4" type="text" name="' . $param_year . '" value="' . $endyear . '">';
$stringtoshow .= '<input type="image" alt="' . $langs->trans("Refresh") . '" src="' . img_picto($langs->trans("Refresh"), 'refresh.png', '', '', 1) . '">';
$stringtoshow .= '</form>';
$stringtoshow .= '</div>';
print '<table class="noborder" width="100%">';
print '<tr class="liste_titre"><th >' . $langs->trans("Statistics") . ' ' . img_picto('', 'filter.png', 'id="idsubimgDOLUSERCOOKIE_ticketsup_by_status" class="linkobject"') . '</th></tr>';
print '<tr><td>';
// don't display graph if no series
if (count($dataseries) >1) {
$data = array();
foreach ($dataseries as $key => $value) {
$data[] = array($value['label'], $value['data']);
}
$px1 = new DolGraph();
$mesg = $px1->isGraphKo();
if (!$mesg) {
$px1->SetData($data);
unset($data1);
$px1->SetPrecisionY(0);
$i = $startyear;
$legend = array();
while ($i <= $endyear) {
$legend[] = $i;
$i++;
}
$px1->SetType(array('pie'));
$px1->SetLegend($legend);
$px1->SetMaxValue($px1->GetCeilMaxValue());
$px1->SetWidth($WIDTH);
$px1->SetHeight($HEIGHT);
$px1->SetYLabel($langs->trans("TicketStatByStatus"));
$px1->SetShading(3);
$px1->SetHorizTickIncrement(1);
$px1->SetPrecisionY(0);
$px1->SetCssPrefix("cssboxes");
$px1->mode = 'depth';
//$px1->SetTitle($langs->trans("TicketStatByStatus"));
$px1->draw($filenamenb, $fileurlnb);
print $px1->show();
print $stringtoshow;
}
}
print '</td></tr>';
print '</table>';
// Build graphic number of object
$data = $stats->getNbByMonth($endyear, $startyear);
print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
/*
* Last tickets
*/
$max = 15;
$sql = "SELECT t.rowid, t.ref, t.track_id, t.datec, t.subject, t.type_code, t.category_code, t.severity_code";
$sql .= ", type.label as type_label, category.label as category_label, severity.label as severity_label";
$sql .= " FROM " . MAIN_DB_PREFIX . "ticketsup as t";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_type as type ON type.code=t.type_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_category as category ON category.code=t.category_code";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticketsup_severity as severity ON severity.code=t.severity_code";
if (!$user->rights->societe->client->voir && !$socid) {
$sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
}
$sql .= ' WHERE t.entity IN (' . getEntity('ticketsup', 1) . ')';
$sql .= " AND t.fk_statut=0";
if (!$user->rights->societe->client->voir && !$socid) {
$sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = " . $user->id;
}
if ($user->societe_id > 0) {
$sql .= " AND t.fk_soc='" . $user->societe_id . "'";
} else {
// Restricted to assigned user only
if ($conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY && !$user->rights->ticketsup->manage) {
$sql .= " AND t.fk_user_assign=" . $user->id;
}
}
$sql .= $db->order("t.datec", "DESC");
$sql .= $db->plimit($max, 0);
//print $sql;
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
$i = 0;
$transRecordedType = $langs->trans("LastNewTickets", $max);
print '<table class="noborder" width="100%">';
print '<tr class="liste_titre"><th>' . $transRecordedType . '</th>';
print '<th>' . $langs->trans('Ref') . '</th>';
print '<th>' . $langs->trans('Subject') . '</th>';
print '<th>' . $langs->trans('Type') . '</th>';
print '<th>' . $langs->trans('Category') . '</th>';
print '<th>' . $langs->trans('Severity') . '</th>';
print '</tr>';
if ($num > 0) {
$var = true;
while ($i < $num) {
$objp = $db->fetch_object($result);
$var = !$var;
print "<tr $bc[$var]>";
// Creation date
print '<td align="left">';
print dol_print_date($db->jdate($objp->datec), 'dayhour');
print "</td>";
// Ref
print '<td class="nowrap">';
print '<a href="card.php?track_id=' . $objp->track_id . '">' . $objp->ref . '</a>';
print "</td>\n";
// Subject
print '<td class="nowrap">';
print '<a href="card.php?track_id=' . $objp->track_id . '">' . dol_trunc($objp->subject, 30) . '</a>';
print "</td>\n";
// Type
print '<td class="nowrap">';
print $objp->type_label;
print '</td>';
// Category
print '<td class="nowrap">';
print $objp->category_label;
print "</td>";
// Severity
print '<td class="nowrap">';
print $objp->severity_label;
print "</td>";
print "</tr>\n";
$i++;
}
$db->free();
} else {
print '<tr><td colspan="5"><div class="info">' . $langs->trans('NoTicketsFound') . '</div></td></tr>';
}
print "</table>";
} else {
dol_print_error($db);
}
print '</div></div></div>';
print '<div style="clear:both"></div>';
print '<div class="tabsAction">';
print '<div class="inline-block divButAction"><a class="butAction" href="new.php?action=create_ticket">' . $langs->trans('CreateTicket') . '</a></div>';
print '<div class="inline-block divButAction"><a class="butAction" href="list.php">' . $langs->trans('TicketList') . '</a></div>';
print '</div>';
// End of page
llxFooter('');
$db->close();

728
htdocs/ticketsup/list.php Normal file
View File

@ -0,0 +1,728 @@
<?php
/**
* Copyright (C) - 2013-2018 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* Tickets List
*
* @package ticketsup
*/
// Load Dolibarr environment
$res=0;
// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME
$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=include(substr($tmp, 0, ($i+1))."/main.inc.php");
if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
// Try main.inc.php using relative path
if (! $res && file_exists("../main.inc.php")) $res=include("../main.inc.php");
if (! $res && file_exists("../../main.inc.php")) $res=include("../../main.inc.php");
if (! $res && file_exists("../../../main.inc.php")) $res=include("../../../main.inc.php");
if (! $res) die("Include of main fails");
require_once 'class/actions_ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
if (!empty($conf->projet->enabled)) {
include DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
include_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php';
}
// Load traductions files requiredby by page
// Load traductions files requiredby by page
$langs->loadLangs(
array(
"ticketsup",
"companies",
"other")
);
// Get parameters
$action = GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
$massaction = GETPOST('massaction','alpha'); // The bulk action (combo box choice into lists)
$show_files = GETPOST('show_files','int'); // Show files area generated by bulk actions ?
$confirm = GETPOST('confirm','alpha'); // Result of a confirmation
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'ticketsuplist'; // To manage different context of search
$backtopage = GETPOST('backtopage','alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss','aZ'); // Option for the css output (always '' except when 'print')
$id = GETPOST('id','int');
$msg_id = GETPOST('msg_id', 'int');
$socid = GETPOST('socid', 'int');
$projectid = GETPOST('projectid', 'int');
$mode = GETPOST('mode', 'alpha');
// Load variable for pagination
$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield','alpha');
$sortorder = GETPOST('sortorder','alpha');
$page = GETPOST('page','int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
// Initialize technical objects
$object=new Ticketsup($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction=$conf->ticketsup->dir_output . '/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('ticketsuplist')); // Note that conf->hooks_modules contains array
// Fetch optionals attributes and labels
$extralabels = $extrafields->fetch_name_optionals_label('ticketsup');
$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
// Default sort order (if not yet defined by previous GETPOST)
if (! $sortfield) $sortfield="t.".key($object->fields); // Set here default search field. By default 1st field in definition.
if (! $sortorder) $sortorder="ASC";
// Initialize array of search criterias
$search_all=trim(GETPOST("search_all",'alpha'));
$search=array();
foreach($object->fields as $key => $val)
{
if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
}
// List of fields to search into when doing a "search in all"
$fieldstosearchall = array();
foreach($object->fields as $key => $val)
{
if ($val['searchall']) $fieldstosearchall['t.'.$key]=$val['label'];
}
// Definition of fields for list
$arrayfields=array();
foreach($object->fields as $key => $val)
{
// If $val['visible']==0, then we never show the field
if (! empty($val['visible'])) $arrayfields['t.'.$key]=array('label'=>$val['label'], 'checked'=>(($val['visible']<0)?0:1), 'enabled'=>$val['enabled'], 'position'=>$val['position']);
}
// Extra fields
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
{
foreach($extrafields->attribute_label as $key => $val)
{
if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>(abs($extrafields->attribute_list[$key])!=3 && $extrafields->attribute_perms[$key]));
}
}
$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
// Filters
// $search_soc = GETPOST("search_soc");
// $search_fk_status = GETPOST("search_fk_status", 'alpha');
// $search_subject = GETPOST("search_subject");
// $search_type = GETPOST("search_type", 'alpha');
// $search_category = GETPOST("search_category", 'alpha');
// $search_severity = GETPOST("search_severity", 'alpha');
// $search_project = GETPOST("search_project", 'int');
// $search_fk_user_create = GETPOST("search_fk_user_create", 'int');
// $search_fk_user_assign = GETPOST("search_fk_user_assign", 'int');
// Security check
if (!$user->rights->ticketsup->read) {
accessforbidden();
}
// Store current page url
$url_page_current = dol_buildpath('/ticketsup/list.php', 1);
/*
* Actions
*
* Put here all code to do according to value of "$action" parameter
*/
if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
$parameters=array();
$reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
if (empty($reshook))
{
// Selection of new fields
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
// Purge search criteria
if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') ||GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
{
foreach($object->fields as $key => $val)
{
$search[$key]='';
}
$toselect='';
$search_array_options=array();
}
if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')
|| GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha'))
{
$massaction=''; // Protection to avoid mass action if we force a new search during a mass action confirmation
}
// Mass actions
$objectclass='Ticketsup';
$objectlabel='Ticketsup';
$permtoread = $user->rights->ticketsup->read;
$permtodelete = $user->rights->ticketsup->delete;
$uploaddir = $conf->ticketsup->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
/***************************************************
* PAGE
*
* Put here all code to build page
****************************************************/
$help_url = 'FR:DocumentationModuleTicket';
llxHeader('', $langs->trans('TicketList'), $help_url);
$form = new Form($db);
$formTicket = new FormTicketsup($db);
$user_assign = new User($db);
$user_create = new User($db);
$socstatic = new Societe($db);
$search_fk_status = GETPOST('search_fk_status', 'alpha');
// Build and execute select
// --------------------------------------------------------------------
$sql = 'SELECT ';
foreach($object->fields as $key => $val)
{
$sql.='t.'.$key.', ';
}
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
// Add fields from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
$sql=preg_replace('/, $/','', $sql);
$sql.= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."ticketsup_extrafields as ef on (t.rowid = ef.fk_object)";
if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity('ticketsup').")";
else $sql.=" WHERE 1 = 1";
foreach($search as $key => $val)
{
$mode_search=(($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key]))?1:0);
if ($search[$key] != '') $sql.=natural_search($key, $search[$key], (($key == 'status')?2:$mode_search));
}
if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all);
if (!$user->societe_id && ($mode == "my_assign" || (!$user->admin && $conf->global->TICKETS_LIMIT_VIEW_ASSIGNED_ONLY))) {
$sql.= " AND t.fk_user_assign=".$user->id;
}
if (isset($search_fk_status) && $search_fk_status == 'non_closed') {
//$search['fk_statut'] = '0,1'; //
$sql.= " AND t.fk_statut IN (0, 1, 3, 4, 5, 6)";
}
// Add where from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
// Add where from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
/* If a group by is required
$sql.= " GROUP BY "
foreach($object->fields as $key => $val)
{
$sql.='t.'.$key.', ';
}
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : '');
// Add where from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
*/
$sql.=$db->order($sortfield,$sortorder);
// Count total nb of records
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
{
$result = $db->query($sql);
$nbtotalofrecords = $db->num_rows($result);
}
// if total resultset is smaller then paging size (filtering), goto and load page 0
if (($page * $limit) > $nbtotalofrecords)
{
$page = 0;
$offset = 0;
}
// if total resultset is smaller the limit, no need to do paging.
if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords)
{
$resql = $result;
$num = $nbtotalofrecords;
}
else
{
$sql.= $db->plimit($limit+1, $offset);
$resql=$db->query($sql);
if (! $resql)
{
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
}
// Direct jump if only one record found
if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all)
{
$obj = $db->fetch_object($resql);
$id = $obj->rowid;
header("Location: ".DOL_URL_ROOT.'/ticketsup/card.php?id='.$id);
exit;
}
// Output page
// --------------------------------------------------------------------
if ($socid && !$projectid && $user->rights->societe->lire) {
$socstat = new Societe($db);
$res = $socstat->fetch($socid);
if ($res > 0) {
$head = societe_prepare_head($socstat);
dol_fiche_head($head, 'ticketsup', $langs->trans("ThirdParty"), 0, 'company');
dol_banner_tab($socstat, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border centpercent">';
// Customer code
if ($socstat->client && !empty($socstat->code_client)) {
print '<tr><td>';
print $langs->trans('CustomerCode') . '</td><td colspan="' . (2 + (($showlogo || $showbarcode) ? 0 : 1)) . '">';
print $socstat->code_client;
if ($socstat->check_codeclient() != 0) {
print ' <font class="error">(' . $langs->trans("WrongCustomerCode") . ')</font>';
}
print '</td>';
print $htmllogobar;
$htmllogobar = '';
print '</tr>';
}
print '</table>';
print '</div>';
dol_fiche_end();
}
}
if ($projectid) {
$projectstat = new Project($db);
if ($projectstat->fetch($projectid) > 0) {
$projectstat->fetch_thirdparty();
// To verify role of users
//$userAccess = $object->restrictedProjectArea($user,'read');
$userWrite = $projectstat->restrictedProjectArea($user, 'write');
//$userDelete = $object->restrictedProjectArea($user,'delete');
//print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
$head = project_prepare_head($projectstat);
dol_fiche_head($head, 'ticketsup', $langs->trans("Project"), 0, ($projectstat->public ? 'projectpub' : 'project'));
/*
* Projet synthese pour rappel
*/
print '<table class="border" width="100%">';
$linkback = '<a href="' . DOL_URL_ROOT . '/projet/list.php">' . $langs->trans("BackToList") . '</a>';
// Ref
print '<tr><td width="30%">' . $langs->trans('Ref') . '</td><td colspan="3">';
// Define a complementary filter for search of next/prev ref.
if (!$user->rights->projet->all->lire) {
$objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0);
$projectstat->next_prev_filter = " rowid in (" . (count($objectsListId) ? join(',', array_keys($objectsListId)) : '0') . ")";
}
print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', '');
print '</td></tr>';
// Label
print '<tr><td>' . $langs->trans("Label") . '</td><td>' . $projectstat->title . '</td></tr>';
// Customer
print "<tr><td>" . $langs->trans("ThirdParty") . "</td>";
print '<td colspan="3">';
if ($projectstat->thirdparty->id > 0) {
print $projectstat->thirdparty->getNomUrl(1);
} else {
print '&nbsp;';
}
print '</td></tr>';
// Visibility
print '<tr><td>' . $langs->trans("Visibility") . '</td><td>';
if ($projectstat->public) {
print $langs->trans('SharedProject');
} else {
print $langs->trans('PrivateProject');
}
print '</td></tr>';
// Statut
print '<tr><td>' . $langs->trans("Status") . '</td><td>' . $projectstat->getLibStatut(4) . '</td></tr>';
print "</table>";
print '</div>';
} else {
print "ErrorRecordNotFound";
}
}
$arrayofselected=is_array($toselect)?$toselect:array();
$param='';
if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
foreach($search as $key => $val)
{
$param.= '&search_'.$key.'='.urlencode($search[$key]);
}
if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
// List of mass actions available
$arrayofmassactions = array(
//'presend'=>$langs->trans("SendByMail"),
//'builddoc'=>$langs->trans("PDFMerge"),
);
if ($user->rights->ticketsup->delete) $arrayofmassactions['predelete']=$langs->trans("Delete");
if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print '<input type="hidden" name="action" value="list">';
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print '<input type="hidden" name="mode" value="' . $mode . '" >';
print_barre_liste($langs->trans('TicketList'), $page, 'list.php', $param, $sortfield, $sortorder, '', $num, $num_total, 'img/ticketsup-32.png', 1);
if ($mode == 'my_assign') {
print '<div class="info">' . $langs->trans('TicketAssignedToMeInfos') . '</div>';
}
// Add code for pre mass action (confirmation or email presend form)
$topicmail="SendTicketsupRef";
$modelmail="ticketsup";
$objecttmp=new Ticketsup($db);
$trackid='xxxx'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
if ($sall)
{
foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall);
}
if ($search_fk_status == 'non_closed') {
print '<div><a href="' . $url_page_current . '?search_fk_status=-1' . ($socid ? '&socid=' . $socid : '') . '">' . $langs->trans('TicketViewAllTickets') . '</a></div>';
$param .= '&search_fk_status=non_closed';
} else {
print '<div><a href="' . $url_page_current . '?search_fk_status=non_closed' . ($socid ? '&socid=' . $socid : '') . '">' . $langs->trans('TicketViewNonClosedOnly') . '</a></div>';
$param .= '&search_fk_status=-1';
}
$moreforfilter = '';
/*$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
$moreforfilter.= '</div>';*/
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint;
else $moreforfilter = $hookmanager->resPrint;
if (! empty($moreforfilter))
{
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
print '</div>';
}
$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
$selectedfields.=(count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
// Fields title search
// --------------------------------------------------------------------
print '<tr class="liste_titre">';
foreach($object->fields as $key => $val)
{
$align='';
if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center';
if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap';
if ($key == 'status') $align.=($align?' ':'').'center';
if (! empty($arrayfields['t.'.$key]['checked'])) {
if ($key == 'fk_statut') {
print '<td class="liste_titre'.($align?' '.$align:'').'">';
$object->printSelectStatus(dol_escape_htmltag($search[$key]));
print '</td>';
} elseif ($key == 'type_code') {
print '<td class="liste_titre'.($align?' '.$align:'').'">';
$formTicket->selectTypesTickets(dol_escape_htmltag($search[$key]), 'search_'.$key.'', '', 2, 1, 1);
print '</td>';
} elseif ($key == 'category_code') {
print '<td class="liste_titre'.($align?' '.$align:'').'">';
$formTicket->selectCategoriesTickets(dol_escape_htmltag($search[$key]), 'search_'.$key.'', '', 2, 1, 1);
print '</td>';
} elseif ($key == 'severity_code') {
print '<td class="liste_titre'.($align?' '.$align:'').'">';
$formTicket->selectSeveritiesTickets(dol_escape_htmltag($search[$key]), 'search_'.$key.'', '', 2, 1, 1);
print '</td>';
} else {
print '<td class="liste_titre'.($align?' '.$align:'').'"><input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag($search[$key]).'"></td>';
}
}
}
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
// Fields from hook
$parameters=array('arrayfields'=>$arrayfields);
$reshook=$hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Action column
print '<td class="liste_titre" align="right">';
$searchpicto=$form->showFilterButtons();
print $searchpicto;
print '</td>';
print '</tr>'."\n";
// Fields title label
// --------------------------------------------------------------------
print '<tr class="liste_titre">';
foreach($object->fields as $key => $val)
{
$align='';
if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center';
if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap';
if ($key == 'status') $align.=($align?' ':'').'center';
if (! empty($arrayfields['t.'.$key]['checked'])) print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n";
}
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
// Hook fields
$parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder);
$reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"],'','','','align="center"',$sortfield,$sortorder,'maxwidthsearch ')."\n";
print '</tr>'."\n";
// Detect if we need a fetch on each output line
$needToFetchEachLine=0;
foreach ($extrafields->attribute_computed as $key => $val)
{
if (preg_match('/\$object/',$val)) $needToFetchEachLine++; // There is at least one compute field that use $object
}
// Loop on record
// --------------------------------------------------------------------
$i=0;
$totalarray=array();
while ($i < min($num, $limit))
{
$obj = $db->fetch_object($resql);
if (empty($obj)) break; // Should not happen
// Store properties in $object
$object->id = $obj->rowid;
foreach($object->fields as $key => $val)
{
if (isset($obj->$key)) $object->$key = $obj->$key;
}
// Show here line of result
print '<tr class="oddeven">';
foreach($object->fields as $key => $val)
{
$align='';
if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center';
if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap';
if ($key == 'status') $align.=($align?' ':'').'center';
if (! empty($arrayfields['t.'.$key]['checked']))
{
print '<td';
if ($align) print ' class="'.$align.'"';
print '>';
print $object->showOutputField($val, $key, $obj->$key, '');
print '</td>';
if (! $i) $totalarray['nbfield']++;
if (! empty($val['isameasure']))
{
if (! $i) $totalarray['pos'][$totalarray['nbfield']]='t.'.$key;
$totalarray['val']['t.'.$key] += $obj->$key;
}
}
}
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
// Fields from hook
$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj);
$reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Action column
print '<td class="nowrap" align="center">';
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 '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>';
}
print '</td>';
if (! $i) $totalarray['nbfield']++;
print '</tr>';
$i++;
}
// Show total line
if (isset($totalarray['pos']))
{
print '<tr class="liste_total">';
$i=0;
while ($i < $totalarray['nbfield'])
{
$i++;
if (! empty($totalarray['pos'][$i])) print '<td align="right">'.price($totalarray['val'][$totalarray['pos'][$i]]).'</td>';
else
{
if ($i == 1)
{
if ($num < $limit) print '<td align="left">'.$langs->trans("Total").'</td>';
else print '<td align="left">'.$langs->trans("Totalforthispage").'</td>';
}
else print '<td></td>';
}
}
print '</tr>';
}
// If no record found
if ($num == 0)
{
$colspan=1;
foreach($arrayfields as $key => $val) { if (! empty($val['checked'])) $colspan++; }
print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
}
$db->free($resql);
$parameters=array('arrayfields'=>$arrayfields, 'sql'=>$sql);
$reshook=$hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print '</table>'."\n";
print '</div>'."\n";
print '</form>'."\n";
print '<div class="tabsAction">';
print '<div class="inline-block divButAction"><a class="butAction" href="new.php?action=create_ticket' . ($socid ? '&socid=' . $socid : '') . ($projectid ? '&origin=projet_project&originid=' . $projectid : '') . '">' . $langs->trans('NewTicket') . '</a></div>';
print '</div>';
if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords))
{
$hidegeneratedfilelistifempty=1;
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty=0;
require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
$formfile = new FormFile($db);
// Show list of available documents
$urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
$urlsource.=str_replace('&amp;','&',$param);
$filedir=$diroutputmassaction;
$genallowed=$user->rights->ticketsup->read;
$delallowed=$user->rights->ticketsup->create;
print $formfile->showdocuments('massfilesarea_ticketsup','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'','','',null,$hidegeneratedfilelistifempty);
}
// End of page
llxFooter('');
$db->close();

106
htdocs/ticketsup/new.php Normal file
View File

@ -0,0 +1,106 @@
<?php
/*
* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
* 2016 Christophe Battarel <christophe@altairis.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 2 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 <http://www.gnu.org/licenses/>.
*/
/**
* Display form to add new ticket
*
* @package ticketsup
*/
$res = 0;
if (file_exists("../main.inc.php")) {
$res = include "../main.inc.php"; // From htdocs directory
} elseif (!$res && file_exists("../../main.inc.php")) {
$res = include "../../main.inc.php"; // From "custom" directory
} else {
die("Include of main fails");
}
require_once 'class/actions_ticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formticketsup.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/ticketsup.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
// Load traductions files requiredby by page
$langs->load("companies");
$langs->load("other");
$langs->load("ticketsup@ticketsup");
// Get parameters
$id = GETPOST('id', 'int');
$socid = GETPOST('socid', 'int');
$contactid = GETPOST('contactid', 'int');
$msg_id = GETPOST('msg_id', 'int');
$notNotifyTiers = GETPOST("not_notify_tiers_at_create", 'alpha');
$notnotifytiersatcreate = !empty($notNotifyTiers);
$action = GETPOST('action', 'alpha', 3);
// Protection if external user
if (!$user->rights->ticketsup->read || !$user->rights->ticketsup->create) {
accessforbidden();
}
$object = new ActionsTicketsup($db);
$object->doActions($action);
/***************************************************
* PAGE
*
* Put here all code to build page
****************************************************/
$help_url = 'FR:DocumentationModuleTicket';
$page_title = $object->getTitle($action);
llxHeader('', $page_title, $help_url);
$form = new Form($db);
if ($action == 'create_ticket') {
$formticket = new FormTicketsup($db);
print load_fiche_titre($langs->trans('NewTicket'), '', 'img/ticketsup-32.png', 1);
$formticket->withfromsocid = $socid ? $socid : $user->societe_id;
$formticket->withfromcontactid = $contactid ? $contactid : '';
$formticket->withtitletopic = 1;
$formticket->withnotnotifytiersatcreate = $notnotifytiersatcreate;
$formticket->withusercreate = 1;
$formticket->withref = 1;
$formticket->fk_user_create = $user->id;
$formticket->withfile = 2;
$formticket->withextrafields = 1;
$formticket->param = array('origin' => GETPOST('origin'), 'originid' => GETPOST('originid'));
if (empty($defaultref)) {
$defaultref = '';
}
$formticket->showForm();
}
/***************************************************
* LINKED OBJECT BLOCK
*
* Put here code to view linked object
****************************************************/
//$somethingshown=$object->showLinkedObjectBlock();
// End of page
llxFooter('');
$db->close();

View File

@ -0,0 +1,61 @@
<?php
/* Copyright (C) 2010-2012 Regis Houssin <regis@dolibarr.fr>
* Copyright (C) 2013 Jean-François FERRY <hello@librethic.io>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
?>
<!-- BEGIN PHP TEMPLATE -->
<?php
$langs = $GLOBALS['langs'];
$langs->load('ticketsup@ticketsup');
$linkedObjectBlock = $GLOBALS['linkedObjectBlock'];
echo '<br />';
print_titre($langs->trans('RelatedTickets'));
?>
<table class="noborder" width="100%">
<tr class="liste_titre">
<td><?php echo $langs->trans("Subject"); ?></td>
<td align="center"><?php echo $langs->trans("DateCreation"); ?></td>
<td align="center"><?php echo $langs->trans("Customer"); ?></td>
<td align="center"><?php echo $langs->trans("Status"); ?></td>
</tr>
<?php
$var=true;
foreach ($linkedObjectBlock as $object) {
$var=!$var;
?>
<tr <?php echo $bc[$var]; ?>>
<td>
<a href="<?php echo dol_buildpath("/ticketsup/card.php", 1).'?track_id='.$object->track_id; ?>">
<?php echo img_object($langs->trans("ShowTicket"), "ticketsup@ticketsup") . ' ' . (! empty($object->subject) ? ' '.$object->subject : ''); ?>
</a>
</td>
<td align="center"><?php echo dol_print_date($object->datec, 'day'); ?></td>
<?php
$object->socid = $object->fk_soc;
$object->fetch_thirdparty();
?>
<td align="center"><?php echo $object->thirdparty->getNomUrl(1); ?></td>
<td align="center"><?php echo $object->getLibstatut(2); ?></td>
</tr>
<?php } ?>
</table>
<!-- END PHP TEMPLATE -->

View File

@ -0,0 +1,423 @@
<?php
/* Copyright (C) 2010 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
* or see http://www.gnu.org/
*/
/**
* \file test/unit/TicketsupTest.php
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI: phpunit filename.php
*/
namespace test\unit;
global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
$res = false;
if (file_exists(dirname(__FILE__).'/../../../../htdocs/master.inc.php')) {
$res = require_once dirname(__FILE__).'/../../../../htdocs/master.inc.php';
} elseif (file_exists(dirname(__FILE__).'/../../../../../htdocs/master.inc.php')) {
$res = require_once dirname(__FILE__).'/../../../../../htdocs/master.inc.php';
} else {
die('Include of mains fails');
}
require_once dirname(__FILE__).'/../../class/ticketsup.class.php';
if (empty($user->id)) {
print "Load permissions for admin user nb 1\n";
$user->fetch(1);
$user->getrights();
}
$conf->global->MAIN_DISABLE_ALL_MAILS=1;
/**
* Class for PHPUnit tests
*
* @backupGlobals disabled
* @backupStaticAttributes enabled
* @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
*/
class TicketsupTest extends \PHPUnit_Framework_TestCase
{
protected $savconf;
protected $savuser;
protected $savlangs;
protected $savdb;
/**
* Constructor
* We save global variables into local variables
*
* @return ContratTest
*/
public function __construct()
{
//$this->sharedFixture
global $conf,$user,$langs,$db;
$this->savconf=$conf;
$this->savuser=$user;
$this->savlangs=$langs;
$this->savdb=$db;
print __METHOD__." db->type=".$db->type." user->id=".$user->id;
//print " - db ".$db->db;
print "\n";
}
// Static methods
public static function setUpBeforeClass()
{
global $conf,$user,$langs,$db;
$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
print __METHOD__."\n";
}
// tear down after class
public static function tearDownAfterClass()
{
global $conf,$user,$langs,$db;
$db->rollback();
print __METHOD__."\n";
}
/**
* Init phpunit tests
*
* @return void
*/
protected function setUp()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
print __METHOD__."\n";
}
/**
* End phpunit tests
*
* @return void
*/
protected function tearDown()
{
print __METHOD__."\n";
}
/**
* testTicketsupCreate
*
* @return int
*/
public function testTicketsupCreate()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
// Try to create one with bad values
$localobject=new \Ticketsup($this->savdb);
$localobject->initAsSpecimen();
$localobject->fk_statut = '\'1=1';
$result=$localobject->create($user);
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, -1);
// Try to create one with correct values
$localobject=new \Ticketsup($this->savdb);
$localobject->initAsSpecimen();
$result=$localobject->create($user);
print __METHOD__." result=".$result."\n";
$this->assertLessThan($result, 0);
return $result;
}
/**
* testTicketsupFetch
*
* @param int $id Id of ticket
* @return int
*
* @depends testTicketsupCreate
* The depends says test is run only if previous is ok
*/
public function testTicketsupFetch($id)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$localobject=new \Ticketsup($this->savdb);
$result=$localobject->fetch($id);
print __METHOD__." id=".$id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupmarkAsRead
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupmarkAsRead($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$result=$localobject->markAsRead($user);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupsetProject
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupsetProject($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$project_id = 1;
$result=$localobject->setProject($project_id);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupsetContract
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupsetContract($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$contract_id = 1;
$result=$localobject->setContract($contract_id);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupsetProgression
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupsetProgression($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$percent = 80;
$result=$localobject->setProgression($percent);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupassignUser
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupassignUser($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$user_id_to_assign = 1;
$result=$localobject->assignUser($user, $user_id_to_assign);
;
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupassignUserOther
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupassignUserOther($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$user_id_to_assign = 2;
$result=$localobject->assignUser($user, $user_id_to_assign);
;
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupcreateTicketLog
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupcreateTicketLog($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$message = 'Test ticket log';
$noemail = 1;
$result=$localobject->createTicketLog($user, $message, $noemail);
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject;
}
/**
* testTicketsupclose
*
* @param Ticketsup $localobject Ticket
* @return int
*
* @depends testTicketsupFetch
* The depends says test is run only if previous is ok
*/
public function testTicketsupclose($localobject)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$result=$localobject->close();
print __METHOD__." id=".$localobject->id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $localobject->id;
}
/**
* testTicketsupDelete
*
* @param int $id Id of ticket
* @return int
*
* @depends testTicketsupclose
* The depends says test is run only if previous is ok
*/
public function testTicketsupDelete($id)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$localobject=new \Ticketsup($this->savdb);
$result=$localobject->fetch($id);
$result=$localobject->delete($user);
print __METHOD__." id=".$id." result=".$result."\n";
$this->assertLessThan($result, 0);
return $result;
}
}