From 22ca858b36a250748b1864759d1db0a1ad4cfb19 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 7 Apr 2019 18:32:01 +0200 Subject: [PATCH] Enhance setup of email collector --- htdocs/admin/emailcollector_card.php | 69 ++++++-- htdocs/admin/ticket.php | 4 +- htdocs/core/class/conf.class.php | 2 +- htdocs/core/class/html.form.class.php | 17 +- .../class/emailcollector.class.php | 153 +++++++++++++++--- .../class/emailcollectorfilter.class.php | 2 +- htdocs/langs/en_US/admin.lang | 8 +- htdocs/langs/en_US/boxes.lang | 2 +- htdocs/ticket/class/ticket.class.php | 2 +- 9 files changed, 216 insertions(+), 43 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 50c54621b51..0ce530aea9f 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -75,6 +75,8 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu //$isdraft = (($object->statut == MyObject::STATUS_DRAFT) ? 1 : 0); //$result = restrictedArea($user, 'mymodule', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); +$debuginfo=''; + /* * Actions @@ -180,11 +182,13 @@ if ($action == 'confirm_collect') $res = $object->doCollectOneCollector(); if ($res > 0) { + $debuginfo = $object->debuginfo; setEventMessages($object->lastresult, null, 'mesgs'); } else { - setEventMessages($object->error, null, 'errors'); + $debuginfo = $object->debuginfo; + setEventMessages($object->error, null, 'errors'); } $action = ''; @@ -443,22 +447,45 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; $arrayoftypes=array( - 'from'=>'MailFrom', - 'to'=>'MailTo', - 'cc'=>'Cc', - 'bcc'=>'Bcc', - 'subject'=>'Subject', - 'body'=>'Body', + 'from'=>array('label'=>'MailFrom', 'data-placeholder'=>'SearchString'), + 'to'=>array('label'=>'MailTo', 'data-placeholder'=>'SearchString'), + 'cc'=>array('label'=>'Cc', 'data-placeholder'=>'SearchString'), + 'bcc'=>array('label'=>'Bcc', 'data-placeholder'=>'SearchString'), + 'subject'=>array('label'=>'Subject', 'data-placeholder'=>'SearchString'), + 'body'=>array('label'=>'Body', 'data-placeholder'=>'SearchString'), + 'header'=>array('label'=>'Header', 'data-placeholder'=>'HeaderKey SearchString'), // HEADER key value 'X1'=>'---', - 'seen'=>'AlreadyRead', - 'unseen'=>'NotRead', + 'seen'=>array('label'=>'AlreadyRead', 'data-noparam'=>1), + 'unseen'=>array('label'=>'NotRead', 'data-noparam'=>1), + 'smaller'=>array('label'=>'SmallerThan', 'data-placeholder'=>'NumberOfBytes'), + 'larger'=>array('label'=>'LargerThan', 'data-placeholder'=>'NumberOfBytes'), 'X2'=>'---', - 'withtrackingid'=>'WithDolTrackingID', - 'withouttrackingid'=>'WithoutDolTrackingID' + 'withtrackingid'=>array('label'=>'WithDolTrackingID', 'data-noparam'=>1), + 'withouttrackingid'=>array('label'=>'WithoutDolTrackingID', 'data-noparam'=>1) ); print $form->selectarray('filtertype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', '', 0, '', 2); + + print "\n"; + print ''."\n"; + print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -470,7 +497,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; - print $langs->trans($arrayoftypes[$rulefilter['type']]); + print $langs->trans($arrayoftypes[$rulefilter['type']]['label']); print ''; print ''.$rulefilter['rulevalue'].''; print ''; @@ -492,8 +519,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Add operation print ''; print ''; - $arrayoftypes=array('loadthirdparty'=>'LoadThirdPartyFromName', 'loadandcreatethirdparty'=>'LoadThirdPartyFromNameOrCreate', 'recordevent'=>'RecordEvent'); + $arrayoftypes=array( + 'loadthirdparty'=>'LoadThirdPartyFromName', + 'loadandcreatethirdparty'=>'LoadThirdPartyFromNameOrCreate', + 'recordevent'=>'RecordEvent'); if ($conf->projet->enabled) $arrayoftypes['project']='CreateLeadAndThirdParty'; + if ($conf->ticket->enabled) $arrayoftypes['ticket']='CreateTicketAndThirdParty'; print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1); print ''; print ''; @@ -517,6 +548,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; print $langs->trans($arrayoftypes[$ruleaction['type']]); + if (in_array($ruleaction['type'], array('recordevent'))) + { + print $form->textwithpicto('', $langs->transnoentitiesnoconv('IfTrackingIDFoundEventWillBeLinked')); + } print ''; print ''.$ruleaction['actionparam'].''; print ''; @@ -571,6 +606,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '' . "\n"; } + if (! empty($debuginfo)) + { + print info_admin($debuginfo); + } + + // Select mail models is same action as presend if (GETPOST('modelselected')) { $action = 'presend'; diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 052e11f1ced..def9a30fc8d 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -66,7 +66,7 @@ if ($action == 'updateMask') { // TODO Verifier si module numerotation choisi peut etre active // par appel methode canBeActivated - dolibarr_set_const($db, "TICKETSUP_ADDON", $value, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "TICKET_ADDON", $value, 'chaine', 0, '', $conf->entity); } elseif ($action == 'setvar') { include_once DOL_DOCUMENT_ROOT . "/core/lib/files.lib.php"; @@ -256,7 +256,7 @@ foreach ($dirmodels as $reldir) { print '' . "\n"; print ''; - if ($conf->global->TICKETSUP_ADDON == 'mod_' . $classname) { + if ($conf->global->TICKET_ADDON == 'mod_' . $classname) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print '' . img_picto($langs->trans("Disabled"), 'switch_off') . ''; diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 12d6b337fd0..861c273e28a 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -447,7 +447,7 @@ class Conf if (empty($this->global->SOCIETE_CODECOMPTA_ADDON)) $this->global->SOCIETE_CODECOMPTA_ADDON="mod_codecompta_panicum"; if (empty($this->global->CHEQUERECEIPTS_ADDON)) $this->global->CHEQUERECEIPTS_ADDON='mod_chequereceipt_mint'; - if (empty($conf->global->TICKETSUP_ADDON)) $this->global->TICKETSUP_ADDON='mod_ticket_simple'; + if (empty($conf->global->TICKET_ADDON)) $this->global->TICKET_ADDON='mod_ticket_simple'; // Security if (empty($this->global->USER_PASSWORD_GENERATED)) $this->global->USER_PASSWORD_GENERATED='standard'; // Default password generator diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 61892f694d7..a54bfc4492d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5828,7 +5828,7 @@ class Form * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. * * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect - * @param array $array Array (key => value) + * @param array $array Array like array(key => value) or array(key=>array('label'=>..., 'data-...'=>...)) * @param string|string[] $id Preselected key or preselected keys for multiselect * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or ' ' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value. * @param int $key_in_label 1 to show key into label with format "[key] value" @@ -5889,7 +5889,8 @@ class Form { foreach($array as $key => $value) { - $array[$key]=$langs->trans($value); + if (! is_array($value)) $array[$key]=$langs->trans($value); + else $array[$key]['label']=$langs->trans($value['label']); } } @@ -5897,8 +5898,11 @@ class Form if ($sort == 'ASC') asort($array); elseif ($sort == 'DESC') arsort($array); - foreach($array as $key => $value) + foreach($array as $key => $tmpvalue) { + if (is_array($tmpvalue)) $value=$tmpvalue['label']; + else $value = $tmpvalue; + $disabled=''; $style=''; if (! empty($disablebademail)) { @@ -5926,6 +5930,13 @@ class Form $out.=$style.$disabled; if ($id != '' && $id == $key && ! $disabled) $out.=' selected'; // To preselect a value if ($nohtmlescape) $out.=' data-html="'.dol_escape_htmltag($selectOptionValue).'"'; + if (is_array($tmpvalue)) + { + foreach($tmpvalue as $keyforvalue => $valueforvalue) + { + if (preg_match('/^data-/', $keyforvalue)) $out.=' '.$keyforvalue.'="'.$valueforvalue.'"'; + } + } $out.='>'; //var_dump($selectOptionValue); $out.=$selectOptionValue; diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index e0f745dabec..386f5de9a91 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -27,6 +27,7 @@ require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT . '/ticket/class/ticket.class.php'; /** @@ -172,6 +173,8 @@ class EmailCollector extends CommonObject public $filters; public $actions; + public $debuginfo; + /** * Constructor @@ -737,7 +740,7 @@ class EmailCollector extends CommonObject $errorforthisaction = 0; // Overwrite values with values extracted from source email - // $this->actionparam = 'opportunity_status=123;abc=REGEX:BODY:....' + // $this->actionparam = 'opportunity_status=123;abc=EXTRACT:BODY:....' $arrayvaluetouse = dolExplodeIntoArray($actionparam, ';', '='); foreach($arrayvaluetouse as $propertytooverwrite => $valueforproperty) { @@ -761,13 +764,13 @@ class EmailCollector extends CommonObject $regexstring=''; //$transformationstring=''; $regforregex=array(); - if (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*):([^:])$/', $valueforproperty, $regforregex)) + if (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*):([^:])$/', $valueforproperty, $regforregex)) { $sourcefield=$regforregex[1]; $regexstring=$regforregex[2]; //$transofrmationstring=$regforregex[3]; } - elseif (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) + elseif (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) { $sourcefield=$regforregex[1]; $regexstring=$regforregex[2]; @@ -789,7 +792,7 @@ class EmailCollector extends CommonObject // Nothing can be done for this param } } - elseif (preg_match('/^VALUE:(.*)$/', $valueforproperty, $reg)) + elseif (preg_match('/^SET:(.*)$/', $valueforproperty, $reg)) { $object->$tmpproperty = $reg[1]; } @@ -820,7 +823,7 @@ class EmailCollector extends CommonObject dol_syslog("EmailCollector::doCollectOneCollector start", LOG_DEBUG); - $langs->loadLangs(array("project", "companies", "mails", "errors")); + $langs->loadLangs(array("project", "companies", "mails", "errors", "ticket")); $error = 0; $this->output = ''; @@ -866,8 +869,14 @@ class EmailCollector extends CommonObject return -3; } + // $conf->global->MAIL_PREFIX_FOR_EMAIL_ID must be defined + $host=dol_getprefix('email'); + + // Define the IMAP search string + // See https://tools.ietf.org/html/rfc3501#section-6.4.4 //$search='ALL'; - $search='UNDELETED'; + $search='UNDELETED NOT DRAFT'; + $searchhead=''; $searchfilterdoltrackid=0; $searchfilternodoltrackid=0; foreach($this->filters as $rule) @@ -880,10 +889,15 @@ class EmailCollector extends CommonObject if ($rule['type'] == 'from') $search.=($search?' ':'').'FROM "'.str_replace('"', '', $rule['rulevalue']).'"'; if ($rule['type'] == 'subject') $search.=($search?' ':'').'SUBJECT "'.str_replace('"', '', $rule['rulevalue']).'"'; if ($rule['type'] == 'body') $search.=($search?' ':'').'BODY "'.str_replace('"', '', $rule['rulevalue']).'"'; + if ($rule['type'] == 'header') $search.=($search?' ':'').'HEADER '.$rule['rulevalue']; + if ($rule['type'] == 'seen') $search.=($search?' ':'').'SEEN'; if ($rule['type'] == 'unseen') $search.=($search?' ':'').'UNSEEN'; - if ($rule['type'] == 'withtrackingid') $searchfilterdoltrackid++; - if ($rule['type'] == 'withouttrackingid') $searchfilternodoltrackid++; + if ($rule['type'] == 'smaller') $search.=($search?' ':'').'SMALLER "'.str_replace('"', '', $rule['rulevalue']).'"'; + if ($rule['type'] == 'larger') $search.=($search?' ':'').'LARGER "'.str_replace('"', '', $rule['rulevalue']).'"'; + + if ($rule['type'] == 'withtrackingid') { $searchfilterdoltrackid++; $searchhead.='/References.*@'.preg_quote($host, '/').'/'; } + if ($rule['type'] == 'withouttrackingid') { $searchfilternodoltrackid++; $searchhead.='! /References.*@'.preg_quote($host, '/').'/';} } if (empty($targetdir)) // Use last date as filter if there is no targetdir defined. @@ -916,11 +930,7 @@ class EmailCollector extends CommonObject $headers = array_combine($matches[1], $matches[2]); //var_dump($headers); - // $conf->global->MAIL_PREFIX_FOR_EMAIL_ID must be defined - $host=dol_getprefix('email'); - // If there is a filter on trackid - //var_dump($host);exit; if ($searchfilterdoltrackid > 0) { //if (empty($headers['X-Dolibarr-TRACKID'])) continue; @@ -1101,8 +1111,10 @@ class EmailCollector extends CommonObject $contactid = 0; $thirdpartyid = 0; $projectid = 0; - // Analyze TrackId in field References - // For example: References: <1542377954.SMTPs-dolibarr-thi649@8f6014fde11ec6cdec9a822234fc557e> + // Analyze TrackId in field References. For example: + // References: <1542377954.SMTPs-dolibarr-thi649@8f6014fde11ec6cdec9a822234fc557e> + // References: <1542377954.SMTPs-dolibarr-tic649@8f6014fde11ec6cdec9a822234fc557e> + // References: <1542377954.SMTPs-dolibarr-abc649@8f6014fde11ec6cdec9a822234fc557e> $trackid = ''; $reg=array(); if (! empty($headers['References']) && preg_match('/dolibarr-([a-z]+)([0-9]+)@'.preg_quote($host, '/').'/', $headers['References'], $reg)) @@ -1136,6 +1148,11 @@ class EmailCollector extends CommonObject $objectid = $reg[1]; $objectemail = new User($this->db); } + if ($reg[0] == 'tic') + { + $objectid = $reg[1]; + $objectemail = new Ticket($this->db); + } if (is_object($objectemail)) { @@ -1233,7 +1250,7 @@ class EmailCollector extends CommonObject if (empty($operation['actionparam'])) { $errorforactions++; - $this->error = "Action loadthirdparty or loadandcreatethirdparty has empty parameter. Must be 'VALUE:xxx' or 'REGEX:(body|subject):regex' to define how to extract data"; + $this->error = "Action loadthirdparty or loadandcreatethirdparty has empty parameter. Must be 'SET:xxx' or 'EXTRACT:(body|subject):regex' to define how to extract data"; $this->errors[] = $this->error; } else @@ -1241,7 +1258,7 @@ class EmailCollector extends CommonObject $actionparam = $operation['actionparam']; $nametouseforthirdparty=''; - // $this->actionparam = 'VALUE:aaa' or 'REGEX:BODY:....' + // $this->actionparam = 'SET:aaa' or 'EXTRACT:BODY:....' $arrayvaluetouse = dolExplodeIntoArray($actionparam, ';', '='); foreach($arrayvaluetouse as $propertytooverwrite => $valueforproperty) { @@ -1250,7 +1267,7 @@ class EmailCollector extends CommonObject $regexstring=''; $regforregex=array(); - if (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) + if (preg_match('/^EXTRACT:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) { $sourcefield=$regforregex[1]; $regexstring=$regforregex[2]; @@ -1273,7 +1290,7 @@ class EmailCollector extends CommonObject } //var_dump($sourcestring); var_dump($regexstring);var_dump($nametouseforthirdparty);exit; } - elseif (preg_match('/^VALUE:(.*)$/', $valueforproperty, $reg)) + elseif (preg_match('/^SET:(.*)$/', $valueforproperty, $reg)) { $nametouseforthirdparty = $reg[1]; } @@ -1338,6 +1355,19 @@ class EmailCollector extends CommonObject { $actioncode = 'EMAIL_IN'; + if ($projectstatic->id > 0) + { + if ($projectfoundby) $messagetext .= ' - Project found from '.$projectfoundby; + } + if ($thirdpartystatic->id > 0) + { + if ($thirdpartyfoundby) $messagetext .= ' - Third party found from '.$thirdpartyfoundby; + } + if ($contactstatic->id > 0) + { + if ($contactfoundby) $messagetext .= ' - Contact/address found from '.$contactfoundby; + } + // Insert record of emails sent $actioncomm = new ActionComm($this->db); @@ -1471,6 +1501,90 @@ class EmailCollector extends CommonObject } } } + // Create event + elseif ($operation['type'] == 'ticket') + { + $note_private = $langs->trans("TicketCreatedByEmailCollector", $msgid); + $tickettocreate = new Ticket($this->db); + if ($thirdpartystatic->id > 0) + { + $tickettocreate->socid = $thirdpartystatic->id; + if ($thirdpartyfoundby) $note_private .= ' - Third party found from '.$thirdpartyfoundby; + } + if ($contactstatic->id > 0) + { + $tickettocreate->contact_id = $contactstatic->id; + if ($contactfoundby) $note_private .= ' - Contact/address found from '.$contactfoundby; + } + + $tickettocreate->title = $subject; + $tickettocreate->type_code = 0; + $tickettocreate->category_code = 0; + $tickettocreate->severity_code = 0; + $tickettocreate->origin_email = $fromstring; + $tickettocreate->fk_user_create = $user->id; + $tickettocreate->entity = $conf->entity; + $tickettocreate->datec = $date; + $tickettocreate->fk_project = $projectstatic->id; + $tickettocreate->fk_soc = $thirdpartystatic->id; + $tickettocreate->notify_tiers_at_create = 0; + //$tickettocreate->fk_contact = $contactstatic->id; + + // Get next project Ref + $defaultref=''; + $modele = empty($conf->global->TICKET_ADDON)?'mod_ticket_simple':$conf->global->TICKET_ADDON; + + // Search template files + $file=''; $classname=''; $filefound=0; $reldir=''; + $dirmodels=array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/ticket/".$modele.'.php', 0); + if (file_exists($file)) + { + $filefound=1; + $classname = $modele; + break; + } + } + + if ($filefound) + { + $result=dol_include_once($reldir."core/modules/ticket/".$modele.'.php'); + $modTicket = new $classname; + + $defaultref = $modTicket->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $tickettocreate); + } + + $tickettocreate->ref = $defaultref; + + // Overwrite values with values extracted from source email + $errorforthisaction = $this->overwritePropertiesOfObject($tickettocreate, $operation['actionparam'], $messagetext, $subject); + + if ($errorforthisaction) + { + $errorforactions++; + } + else + { + if (is_numeric($tickettocreate->ref) && $tickettocreate->ref <= 0) + { + $errorforactions++; + $this->error = 'Failed to create ticket: Can\'t get a valid value for ticket Ref'; + } + else + { + // Create project + $result = $tickettocreate->create($user); + if ($result <= 0) + { + $errorforactions++; + $this->error = 'Failed to create ticket: '.$langs->trans($tickettocreate->error); + $this->errors = $tickettocreate->errors; + } + } + } + } if (! $errorforactions) { @@ -1537,6 +1651,9 @@ class EmailCollector extends CommonObject $this->datelastresult = $now; $this->lastresult = $output; + $this->debuginfo = 'IMAP search string used : '.$search; + if ($searchhead) $this->debuginfo .= '
Then search string into email header : '.$searchhead; + if (! empty($this->errors)) $this->lastresult.= " - ".join(" - ", $this->errors); $this->codelastresult = ($error ? 'KO' : 'OK'); diff --git a/htdocs/emailcollector/class/emailcollectorfilter.class.php b/htdocs/emailcollector/class/emailcollectorfilter.class.php index d46dfb1c9ae..75a94436ff9 100644 --- a/htdocs/emailcollector/class/emailcollectorfilter.class.php +++ b/htdocs/emailcollector/class/emailcollectorfilter.class.php @@ -162,7 +162,7 @@ class EmailCollectorFilter extends CommonObject if (! in_array($this->type, array('seen','unseen','withtrackingid','withouttrackingid')) && empty($this->rulevalue)) { $langs->load("errors"); - $this->errors[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("StringToFilter")); + $this->errors[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("SearchString")); return -1; } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 08dbd8b4664..1e127a3d063 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1838,6 +1838,7 @@ NothingProcessed=Nothing done XEmailsDoneYActionsDone=%s emails qualified, %s emails successfully processed (for %s record/actions done) by collector RecordEvent=Record email event CreateLeadAndThirdParty=Create lead (and third party if necessary) +CreateTicketAndThirdParty=Create ticket (and third party if necessary) CodeLastResult=Result code of last collect NbOfEmailsInInbox=Number of emails in source directory LoadThirdPartyFromName=Load third party from name (load only) @@ -1847,7 +1848,7 @@ WithoutDolTrackingID=Dolibarr Tracking ID not found FormatZip=Zip MainMenuCode=Menu entry code (mainmenu) ECMAutoTree=Show automatic ECM tree -OperationParamDesc=Define values to use for action, or how to extract values. For example:
VALUE:abc
REGEX:SUBJECT:([^\s]*)
REGEX:BODY:My company name is\s([^\s]*) +OperationParamDesc=Define values to use for action, or how to extract values. For example:
objproperty1=SET:abc
objproperty2=EXTRACT:HEADER:X-Myheaderkey.*[^\s]+(.*)
objproperty3=EXTRACT:SUBJECT:([^\s]*)
objproperty4=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. OpeningHours=Opening hours OpeningHoursDesc=Enter here the regular opening hours of your company. ResourceSetup=Configuration of Resource module @@ -1875,4 +1876,7 @@ WarningValueHigherSlowsDramaticalyOutput=Warning, higher values slows dramatical DebugBarModuleActivated=Module debugbar is activated and slows dramaticaly the interface EXPORTS_SHARE_MODELS=Export models are share with everybody ExportSetup=Setup of module Export -InstanceUniqueID=Unique ID of the instance \ No newline at end of file +InstanceUniqueID=Unique ID of the instance +SmallerThan=Smaller than +LargerThan=Larger than +IfTrackingIDFoundEventWillBeLinked=Note that If a tracking ID is found into incoming email, the event will be automatically linked to the related objects. \ No newline at end of file diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index 41a711f7b5b..b1ab8e41fbc 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -35,7 +35,7 @@ BoxTitleOldestUnpaidCustomerBills=Customer Invoices: oldest %s unpaid BoxTitleOldestUnpaidSupplierBills=Vendor Invoices: oldest %s unpaid BoxTitleCurrentAccounts=Open Accounts: balances BoxTitleLastModifiedContacts=Contacts/Addresses: last %s modified -BoxMyLastBookmarks=Bookmarks: last %s +BoxMyLastBookmarks=Bookmarks: latest %s BoxOldestExpiredServices=Oldest active expired services BoxLastExpiredServices=Latest %s oldest contacts with active expired services BoxTitleLastActionsToDo=Latest %s actions to do diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index c603c0489cb..759360a8e84 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2365,7 +2365,7 @@ class Ticket extends CommonObject global $conf; $defaultref = ''; - $modele = empty($conf->global->TICKETSUP_ADDON) ? 'mod_ticket_simple' : $conf->global->TICKETSUP_ADDON; + $modele = empty($conf->global->TICKET_ADDON) ? 'mod_ticket_simple' : $conf->global->TICKET_ADDON; // Search template files $file = '';