diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index 88a7db9b1d7..4df687dd2bd 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -42,21 +42,24 @@ $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'ticket'; -$error = 0; /* * Actions */ +$error = 0; +$errors = array(); if ($action == 'setTICKET_ENABLE_PUBLIC_INTERFACE') { if (GETPOST('value')) { - dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 1, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 1, 'chaine', 0, '', $conf->entity); } else { - dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 0, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 0, 'chaine', 0, '', $conf->entity); } -} - -if ($action == 'setvar') { + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } +} elseif ($action == 'setvar') { include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; if (GETPOSTISSET('TICKET_ENABLE_PUBLIC_INTERFACE')) { // only for no js case @@ -64,14 +67,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', $param_enable_public_interface, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; - } - } - - if (GETPOSTISSET('TICKET_EMAIL_MUST_EXISTS')) { // only for no js case - $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; + $errors[] = $db->lasterror(); } } @@ -80,6 +76,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_DISABLE_CUSTOMER_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } @@ -88,6 +85,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_SHOW_COMPANY_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } @@ -99,6 +97,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $text_home = GETPOST('TICKET_PUBLIC_TEXT_HOME', 'restricthtml'); @@ -109,6 +108,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $text_help = GETPOST('TICKET_PUBLIC_TEXT_HELP_MESSAGE', 'restricthtml'); @@ -119,6 +119,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $mail_new_ticket = GETPOST('TICKET_MESSAGE_MAIL_NEW', 'restricthtml'); @@ -129,6 +130,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $url_interface = GETPOST('TICKET_URL_PUBLIC_INTERFACE', 'alpha'); @@ -139,12 +141,14 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $param_public_notification_new_message_default_email = GETPOST('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL', 'alpha'); $res = dolibarr_set_const($db, 'TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL', $param_public_notification_new_message_default_email, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { @@ -152,10 +156,60 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } +} elseif (preg_match('/set_(.*)/', $action, $reg)) { + $code = $reg[1]; + $value = GETPOSTISSET($code) ? GETPOST($code, 'int') : 1; + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + + if (!$error) { + if ($code == 'TICKET_EMAIL_MUST_EXISTS') { + $res = dolibarr_del_const($db, 'TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + } elseif ($code == 'TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST') { + $res = dolibarr_del_const($db, 'TICKET_EMAIL_MUST_EXISTS', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + + // enable captcha by default + $res = dolibarr_set_const($db, 'MAIN_SECURITY_ENABLECAPTCHA', 1, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + } + } +} elseif (preg_match('/del_(.*)/', $action, $reg)) { + $code = $reg[1]; + $res = dolibarr_del_const($db, $code, $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } } +if ($action != '') { + if (!$error) { + $db->commit(); + setEventMessage($langs->trans('SetupSaved')); + header("Location: " . $_SERVER['PHP_SELF']); + exit; + } else { + $db->rollback(); + setEventMessages('', $errors, 'errors'); + } +} /* @@ -180,7 +234,7 @@ $head = ticketAdminPrepareHead(); print dol_get_fiche_head($head, 'public', $langs->trans("Module56000Name"), -1, "ticket"); -print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; +print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php?entity='.$conf->entity, 2).''; print dol_get_fiche_end(); @@ -220,11 +274,10 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { // Check if email exists print ''.$langs->trans("TicketsEmailMustExist").''; print ''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_EMAIL_MUST_EXISTS'); + if (empty(getDolGlobalInt('TICKET_EMAIL_MUST_EXISTS'))) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_EMAIL_MUST_EXISTS", $arrval, $conf->global->TICKET_EMAIL_MUST_EXISTS); + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; } print ''; print ''; @@ -232,6 +285,20 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print ''; print ''; + // Create third-party with contact if email not linked to a contact + print ''.$langs->trans("TicketCreateThirdPartyWithContactIfNotExist").''; + print ''; + if (empty(getDolGlobalInt('TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST'))) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; + } else { + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; + } + print ''; + print ''; + print $form->textwithpicto('', $langs->trans("TicketCreateThirdPartyWithContactIfNotExistHelp"), 1, 'help'); + print ''; + print ''; + /*if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // Show logo for module diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 331fe542cb4..a7cc3a996b4 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -127,12 +127,13 @@ class FormTicket /** * Show the form to input ticket * - * @param int $withdolfichehead With dol_get_fiche_head() and dol_get_fiche_end() - * @param string $mode Mode ('create' or 'edit') - * @param int $public 1=If we show the form for the public interface + * @param int $withdolfichehead With dol_get_fiche_head() and dol_get_fiche_end() + * @param string $mode Mode ('create' or 'edit') + * @param int $public 1=If we show the form for the public interface + * @param Contact|null $with_contact [=NULL] Contact to link to this ticket if exists * @return void */ - public function showForm($withdolfichehead = 0, $mode = 'edit', $public = 0) + public function showForm($withdolfichehead = 0, $mode = 'edit', $public = 0, Contact $with_contact = null) { global $conf, $langs, $user, $hookmanager; @@ -178,10 +179,104 @@ class FormTicket } // TITLE + $email = GETPOSTISSET('email') ? GETPOST('email', 'alphanohtml') : ''; if ($this->withemail) { print ''; - print ''; + print ''; print ''; + + if ($with_contact) { + // contact search and result + $html_contact_search = ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + $html_contact_search .= ''; + print $html_contact_search; + // contact lastname + $html_contact_lastname = ''; + $html_contact_lastname .= ''; + $html_contact_lastname .= ''; + $html_contact_lastname .= ''; + print $html_contact_lastname; + // contact firstname + $html_contact_firstname = ''; + $html_contact_firstname .= ''; + $html_contact_firstname .= ''; + $html_contact_firstname .= ''; + print $html_contact_firstname; + // company name + $html_company_name = ''; + $html_company_name .= ''; + $html_company_name .= ''; + $html_company_name .= ''; + print $html_company_name; + // contact phone + $html_contact_phone = ''; + $html_contact_phone .= ''; + $html_contact_phone .= ''; + $html_contact_phone .= ''; + print $html_contact_phone; + + // search contact form email + $langs->load('errors'); + print ''; + } } // If ticket created from another object @@ -325,7 +420,7 @@ class FormTicket print ''; print ''; print ''; - print ''.img_picto($langs->trans("Refresh"), 'refresh', 'id="captcha_refresh_img"').''; + print ''.img_picto($langs->trans("Refresh"), 'refresh', 'id="captcha_refresh_img"').''; print ''; print ''; } diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index 2e70bfba3b9..5b220553bfe 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -233,7 +233,7 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ print '
'; print '
'; if ($urllogo) { - print ''; + print ''; print ''; print ''; diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 60b2b424aaa..b39d3243376 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -286,6 +286,7 @@ ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency=You try to pay in ErrorInvoiceLoadThirdParty=Can't load third-party object for invoice "%s" ErrorInvoiceLoadThirdPartyKey=Third-party key "%s" no set for invoice "%s" ErrorDeleteLineNotAllowedByObjectStatus=Delete line is not allowed by actual object status +ErrorAjaxRequestFailed=Request failed # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index c1cfa5e9757..76d6923e43c 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -99,6 +99,8 @@ TicketNewEmailBodyHelp=The text specified here will be inserted into the email c 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. +TicketCreateThirdPartyWithContactIfNotExist=Create a third party with contact if it does not exist with the given email +TicketCreateThirdPartyWithContactIfNotExistHelp=Create a third party with contact if it does not exist with the given email PublicInterface=Public interface TicketUrlPublicInterfaceLabelAdmin=Alternative URL for public interface TicketUrlPublicInterfaceHelpAdmin=It is possible to define an alias to the web server and thus make available the public interface with another URL (the server must act as a proxy on this new URL) diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index c45a66e7d08..234dc56941c 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -283,6 +283,7 @@ ErrorAttributeIsUsedIntoProduct=Cet attribut est utilisé dans une ou plusieurs ErrorAttributeValueIsUsedIntoProduct=Cette valeur d'attribut est utilisée dans une ou plusieurs variantes de produit ErrorPaymentInBothCurrency=Erreur, tous les montants doivent être entrés dans la même colonne. ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency=Vous essayez de payer une facture en monnaie %s depuis un compte en %s +ErrorAjaxRequestFailed=La requête a échoué # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Votre paramètre PHP upload_max_filesize (%s) est supérieur au paramètre PHP post_max_size (%s). Ceci n'est pas une configuration cohérente. diff --git a/htdocs/langs/fr_FR/ticket.lang b/htdocs/langs/fr_FR/ticket.lang index 0c1338ababa..486e3799f72 100644 --- a/htdocs/langs/fr_FR/ticket.lang +++ b/htdocs/langs/fr_FR/ticket.lang @@ -99,6 +99,8 @@ TicketNewEmailBodyHelp=Le texte spécifié ici sera inséré dans l'e-mail confi TicketParamPublicInterface=Configuration de l'interface publique\n TicketsEmailMustExist=Une adresse e-mail existante est requise pour créer un ticket TicketsEmailMustExistHelp=Pour accéder à l'interface publique et créer un nouveau ticket, votre compte doit déjà être existant. +TicketCreateThirdPartyWithContactIfNotExist=Créer un tiers avec contact s'il n'existe pas avec l'email saisi +TicketCreateThirdPartyWithContactIfNotExistHelp=Créer un tiers avec contact s'il n'existe pas avec l'email saisi PublicInterface=Interface publique TicketUrlPublicInterfaceLabelAdmin=URL alternative pour l'interface publique TicketUrlPublicInterfaceHelpAdmin=Il est possible de définir un alias vers le serveur et de rendre ainsi l'interface publique accessible avec une autre URL (le serveur doit agir comme un proxy sur cette nouvelle URL) diff --git a/htdocs/public/ticket/ajax/ajax.php b/htdocs/public/ticket/ajax/ajax.php new file mode 100644 index 00000000000..a75c796539c --- /dev/null +++ b/htdocs/public/ticket/ajax/ajax.php @@ -0,0 +1,87 @@ + + * + * 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 . + */ + +/** + * \file htdocs/public/ticket/ajax/ajax.php + * \brief Ajax component for Ticket. + */ + +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); // Disables token renewal +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (!defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +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 (!defined('NOIPCHECK')) { + define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +} +if (!defined('NOBROWSERNOTIF')) { + define('NOBROWSERNOTIF', '1'); +} + +include_once '../../../main.inc.php'; // Load $user and permissions + +$action = GETPOST('action', 'aZ09'); +$id = GETPOST('id', 'int'); +$email = GETPOST('email', 'alphanohtml'); + + +/* + * View + */ + +top_httphead(); + +if ($action == 'getContacts') { + $return = array( + 'contacts' => array(), + 'error' => '', + ); + + if (!empty($email)) { + require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; + + $ticket = new Ticket($db); + $contacts = $ticket->searchContactByEmail($email); + if (is_array($contacts)) { + $return['contacts'] = $contacts; + } else { + $return['error'] = $ticket->errorsToString(); + } + } + + echo json_encode($return); + exit(); +} diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 371789edc62..f7e6e023a7f 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -63,6 +63,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; // Load translation files required by the page $langs->loadLangs(array('companies', 'other', 'mails', 'ticket')); @@ -78,6 +79,11 @@ $hookmanager->initHooks(array('publicnewticketcard', 'globalcard')); $object = new Ticket($db); $extrafields = new ExtraFields($db); +$contacts = array(); +$with_contact = null; +if (!empty($conf->global->TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST)) { + $with_contact = new Contact($db); +} $extrafields->fetch_name_optionals_label($object->table_element); @@ -153,18 +159,50 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) { } } + $contact_lastname = ''; + $contact_firstname = ''; + $company_name = ''; + $contact_phone = ''; + if ($with_contact) { + // set linked contact to add in form + if (is_array($contacts) && count($contacts) == 1) { + $with_contact = current($contacts); + } + + // check mandatory fields on contact + $contact_lastname = trim(GETPOST('contact_lastname', 'alphanohtml')); + $contact_firstname = trim(GETPOST('contact_firstname', 'alphanohtml')); + $company_name = trim(GETPOST('company_name', 'alphanohtml')); + $contact_phone = trim(GETPOST('contact_phone', 'alphanohtml')); + if (!($with_contact->id > 0)) { + // check lastname + if (empty($contact_lastname)) { + $error++; + array_push($object->errors, $langs->trans('ErrorFieldRequired', $langs->transnoentities('Lastname'))); + $action = ''; + } + // check firstname + if (empty($contact_firstname)) { + $error++; + array_push($object->errors, $langs->trans('ErrorFieldRequired', $langs->transnoentities('Firstname'))); + $action = ''; + } + } + } + if (!GETPOST("subject", "restricthtml")) { $error++; array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject"))); $action = ''; - } elseif (!GETPOST("message", "restricthtml")) { + } + if (!GETPOST("message", "restricthtml")) { $error++; - array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("message"))); + array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Message"))); $action = ''; } // Check email address - if (!isValidEmail($origin_email)) { + if (!empty($origin_email) && !isValidEmail($origin_email)) { $error++; array_push($object->errors, $langs->trans("ErrorBadEmailAddress", $langs->transnoentities("email"))); $action = ''; @@ -193,6 +231,48 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) { $object->type_code = GETPOST("type_code", 'aZ09'); $object->category_code = GETPOST("category_code", 'aZ09'); $object->severity_code = GETPOST("severity_code", 'aZ09'); + + if (!is_object($user)) { + $user = new User($db); + } + + // create third-party with contact + $usertoassign = 0; + if ($with_contact && !($with_contact->id > 0)) { + $company = new Societe($db); + if (!empty($company_name)) { + $company->name = $company_name; + } else { + $company->particulier = 1; + $company->name = dolGetFirstLastname($contact_firstname, $contact_lastname); + } + $result = $company->create($user); + if ($result < 0) { + $error++; + $errors = ($company->error ? array($company->error) : $company->errors); + array_push($object->errors, $errors); + $action = 'create_ticket'; + } + + // create contact and link to this new company + if (!$error) { + $with_contact->email = $origin_email; + $with_contact->lastname = $contact_lastname; + $with_contact->firstname = $contact_firstname; + $with_contact->socid = $company->id; + $with_contact->phone_pro = $contact_phone; + $result = $with_contact->create($user); + if ($result < 0) { + $error++; + $errors = ($with_contact->error ? array($with_contact->error) : $with_contact->errors); + array_push($object->errors, $errors); + $action = 'create_ticket'; + } else { + $contacts = array($with_contact); + } + } + } + if (is_array($searched_companies)) { $object->fk_soc = $searched_companies[0]->id; } @@ -206,9 +286,6 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) { // Generate new ref $object->ref = $object->getDefaultRef(); - if (!is_object($user)) { - $user = new User($db); - } $object->context['disableticketemail'] = 1; // Disable emails sent by ticket trigger when creation is done from this page, emails are already sent later @@ -402,7 +479,7 @@ if ($action != "infos_success") { print '
'; } else { print '
'.$langs->trans('TicketPublicInfoCreateTicket').'
'; - $formticket->showForm(0, 'edit', 1); + $formticket->showForm(0, 'edit', 1, $with_contact); } }