diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 578bd592a75..a13037402f8 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -113,13 +113,14 @@ Also, some code changes need a prior approbation: * if you add a new table, you must first create a page on http://wiki.dolibarr.org/index.php/Category:Table_SQL (copy an existing page changing its name to see it into this index page). Than ask the project manager (@eldy) if the new data model you plan to add can be accepted as you suggest. -Once a PR has been submitted, you may need to wait for its integration. It is common that the project leader let the PR open for a long delay to allow -every developer discuss about the PR. -If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. -If the PR is valid, and is kept open for a long time, a tag will also be added on the PR to describe the status of your PR. -By putting your mouse on the tag, you will get a full explanation of the tag/status that explain why your PR has not been integrated yet. -Around 95% of submitted PR are reviewed and tagged. Even if this is one of the most important ratio in Open Source world, don't expect the core team -to reach the 100%. With the increasing popularity of Dolibarr, this ratio will probably decrease in future. +Once a PR has been submitted, you may need to wait for its integration. It is common that the project leader let the PR open for a long delay to allow every developer discuss about the PR. + +If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration. + +If the PR is valid, and is kept open for a long time, a tag will also be added on the PR to describe the status of your PR and why the PR is kept open. By putting your mouse on the tag, you will get a full explanation of the tag/status that explain why your PR has not been integrated yet. +In most cases, it give you information of things you have to do to have the PR taken into consideration (for example a change is requested, a conflict is expected to be solved, some questions were asked). If you have a yellow, red flag of purple flag, don't expect to have your PR validated. You must first provide the answer the flag ask you. The majority of PR are waiting a developer action. + +Around 95% of submitted PR are reviewed and tagged. Even if this is one of the most important ratio of answered PR in Open Source world, don't expect the core team to reach the 100%. With the increasing popularity of Dolibarr, this ratio will probably decrease in future. ### Resources diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index ea174638a2a..0e7047b84de 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -374,9 +374,9 @@ if ($result) { // Ref Product print ''; - if ($product_static->id) - print $product_static->getNomUrl(1); - if ($objp->product_label) print '
'.$objp->product_label; + if ($product_static->id > 0) print $product_static->getNomUrl(1); + if ($product_static->id > 0 && $objp->product_label) print '
'; + if ($objp->product_label) print $objp->product_label; print ''; print ''; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 192585ccedd..b738933c89c 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -319,8 +319,8 @@ if ($result) { $arrayofselected=is_array($toselect)?$toselect:array(); $param=''; - if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; - if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); if ($search_lineid) $param.='&search_lineid='.urlencode($search_lineid); if ($search_day) $param.='&search_day='.urlencode($search_day); if ($search_month) $param.='&search_month='.urlencode($search_month); @@ -330,8 +330,8 @@ if ($result) { if ($search_desc) $param.='&search_desc='.urlencode($search_desc); if ($search_amount) $param.='&search_amount='.urlencode($search_amount); if ($search_vat) $param.='&search_vat='.urlencode($search_vat); - if ($search_country) $param .= "&search_country=" . urlencode($search_country); - if ($search_tvaintra) $param .= "&search_tvaintra=" . urlencode($search_tvaintra); + if ($search_country) $param.= "&search_country=".urlencode($search_country); + if ($search_tvaintra) $param.= "&search_tvaintra=".urlencode($search_tvaintra); $arrayofmassactions = array( 'ventil'=>$langs->trans("Ventilate") @@ -403,7 +403,7 @@ if ($result) { print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("ProductDescription", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 '); print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index a67386f6fbd..c4aa1316876 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -384,9 +384,9 @@ if ($result) { // Ref product print ''; - if ($product_static->id) - print $product_static->getNomUrl(1); - if ($objp->product_label) print '
'.$objp->product_label; + if ($product_static->id > 0) print $product_static->getNomUrl(1); + if ($product_static->id > 0 && $objp->product_label) print '
'; + if ($objp->product_label) print $objp->product_label; print ''; // Description diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index b3a426bbf5e..9ce49b23e6a 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -405,7 +405,7 @@ if ($result) { print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("ProductDescription", $_SERVER["PHP_SELF"], "l.description", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "l.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 '); print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 649bfab3d97..4c5c02d0b3d 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -40,7 +40,7 @@ $cancel = GETPOST('cancel', 'alpha'); $search_event = GETPOST('search_event', 'alpha'); // Get list of triggers available -$sql = "SELECT a.rowid, a.code, a.label, a.elementtype"; +$sql = "SELECT a.rowid, a.code, a.label, a.elementtype, a.rang as position"; $sql.= " FROM ".MAIN_DB_PREFIX."c_action_trigger as a"; $sql.= " ORDER BY a.rang ASC"; $resql=$db->query($sql); @@ -55,6 +55,7 @@ if ($resql) $triggers[$i]['code'] = $obj->code; $triggers[$i]['element'] = $obj->elementtype; $triggers[$i]['label'] = ($langs->trans("Notify_".$obj->code)!="Notify_".$obj->code?$langs->trans("Notify_".$obj->code):$obj->label); + $triggers[$i]['position'] = $obj->position; $i++; } @@ -65,6 +66,8 @@ else dol_print_error($db); } +//$triggers = dol_sort_array($triggers, 'code', 'asc', 0, 0, 1); + /* * Actions diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index a0b8f2e50de..5fd40fb032a 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -1027,15 +1027,35 @@ if ($mode == 'deploy') print $langs->trans("YouCanSubmitFile"); - $max=$conf->global->MAIN_UPLOAD_DOC; // En Kb - $maxphp=@ini_get('upload_max_filesize'); // En inconnu + $max=$conf->global->MAIN_UPLOAD_DOC; // In Kb + $maxphp=@ini_get('upload_max_filesize'); // In unknown if (preg_match('/k$/i', $maxphp)) $maxphp=$maxphp*1; if (preg_match('/m$/i', $maxphp)) $maxphp=$maxphp*1024; if (preg_match('/g$/i', $maxphp)) $maxphp=$maxphp*1024*1024; if (preg_match('/t$/i', $maxphp)) $maxphp=$maxphp*1024*1024*1024; - // Now $max and $maxphp are in Kb + $maxphp2=@ini_get('post_max_size'); // In unknown + if (preg_match('/k$/i', $maxphp2)) $maxphp2=$maxphp2*1; + if (preg_match('/m$/i', $maxphp2)) $maxphp2=$maxphp2*1024; + if (preg_match('/g$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024; + if (preg_match('/t$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024*1024; + // Now $max and $maxphp and $maxphp2 are in Kb $maxmin = $max; - if ($maxphp > 0) $maxmin=min($max, $maxphp); + $maxphptoshow = $maxphptoshowparam = ''; + if ($maxphp > 0) + { + $maxmin=min($max, $maxphp); + $maxphptoshow = $maxphp; + $maxphptoshowparam = 'upload_max_filesize'; + } + if ($maxphp2 > 0) + { + $maxmin=min($max, $maxphp2); + if ($maxphp2 < $maxphp) + { + $maxphptoshow = $maxphp2; + $maxphptoshowparam = 'post_max_size'; + } + } if ($maxmin > 0) { @@ -1063,7 +1083,7 @@ if ($mode == 'deploy') { $langs->load('other'); print ' '; - print info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphp), 1); + print info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow, $maxphptoshowparam), 1); } } else diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php index 2dc9406eb13..d1c737ef5a8 100644 --- a/htdocs/admin/system/phpinfo.php +++ b/htdocs/admin/system/phpinfo.php @@ -48,14 +48,31 @@ if (isset($title)) } +// Check PHP setup is OK +$maxphp=@ini_get('upload_max_filesize'); // In unknown +if (preg_match('/k$/i', $maxphp)) $maxphp=$maxphp*1; +if (preg_match('/m$/i', $maxphp)) $maxphp=$maxphp*1024; +if (preg_match('/g$/i', $maxphp)) $maxphp=$maxphp*1024*1024; +if (preg_match('/t$/i', $maxphp)) $maxphp=$maxphp*1024*1024*1024; +$maxphp2=@ini_get('post_max_size'); // In unknown +if (preg_match('/k$/i', $maxphp2)) $maxphp2=$maxphp2*1; +if (preg_match('/m$/i', $maxphp2)) $maxphp2=$maxphp2*1024; +if (preg_match('/g$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024; +if (preg_match('/t$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024*1024; +if ($maxphp > 0 && $maxphp2 > 0 && $maxphp > $maxphp2) +{ + $langs->load("errors"); + print info_admin($langs->trans("WarningParamUploadMaxFileSizeHigherThanPostMaxSize", @ini_get('upload_max_filesize'), @ini_get('post_max_size')), 0, 0, 0, 'warning'); + print '
'; +} + print ''; print ''; print "\n"; -$var=false; -// Recupere la version de PHP +// Get PHP version $phpversion=version_php(); print '\n"; diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index 61d79e4abbb..910772d87ca 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -43,7 +43,7 @@ $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; // Load translation files required by the page $langs->load("propal"); -$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc'); +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); $total=0; $ilink=0; foreach($linkedObjectBlock as $key => $objectlink) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 488f512db56..29688b7d690 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2116,7 +2116,7 @@ if ($action == 'create' && $user->rights->commande->creer) print '
'; print '
'; - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Version")."".$phpversion."
'; + print '
'; if ($soc->outstanding_limit) { @@ -2454,7 +2454,7 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; print ''; - print ''; + print ''; // Close fichecenter print '

'; diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 1f8b440749f..74a2243d633 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -39,7 +39,7 @@ $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; // Load translation files required by the page $langs->load("orders"); -$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc'); +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); $total=0; $ilink=0; foreach($linkedObjectBlock as $key => $objectlink) diff --git a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php index a9fbb5da2eb..bef705a21ab 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php @@ -38,7 +38,7 @@ $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; $langs->load("bills"); -$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc'); +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); $total=0; $ilink=0; foreach($linkedObjectBlock as $key => $objectlink) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 9c403b98104..0d76b83cb8a 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -489,7 +489,10 @@ class Conf if (empty($this->global->ACCOUNTING_MODE)) $this->global->ACCOUNTING_MODE='RECETTES-DEPENSES'; // By default. Can be 'RECETTES-DEPENSES' ou 'CREANCES-DETTES' // By default, suppliers objects can be linked to all projects - $this->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS = 1; + if (! isset($this->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)) $this->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS = 1; + + // By default we enable feature to bill time spent + if (! isset($this->global->PROJECT_BILL_TIME_SPENT)) $this->global->PROJECT_BILL_TIME_SPENT = 1; // MAIN_HTML_TITLE if (! isset($this->global->MAIN_HTML_TITLE)) $this->global->MAIN_HTML_TITLE='noapp,thirdpartynameonly,contactnameonly,projectnameonly'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 711c48053f1..df000b2e857 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6672,7 +6672,8 @@ class Form 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'), 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'), 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled , 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'), - 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')') + 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>1, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')'), + 'ticket'=>array('enabled'=>$conf->ticket->enabled , 'perms'=>1, 'label'=>'LinkToTicket', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.track_id, '0' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."ticket as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('ticket').')') ); } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index be389a94283..5f63d4db66c 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -130,15 +130,35 @@ class FormFile $out .= ''; // Input file name box - print ''; print ''; print '
'; - $max=$conf->global->MAIN_UPLOAD_DOC; // En Kb - $maxphp=@ini_get('upload_max_filesize'); // En inconnu + $max=$conf->global->MAIN_UPLOAD_DOC; // In Kb + $maxphp=@ini_get('upload_max_filesize'); // In unknown if (preg_match('/k$/i', $maxphp)) $maxphp=$maxphp*1; if (preg_match('/m$/i', $maxphp)) $maxphp=$maxphp*1024; if (preg_match('/g$/i', $maxphp)) $maxphp=$maxphp*1024*1024; if (preg_match('/t$/i', $maxphp)) $maxphp=$maxphp*1024*1024*1024; - // Now $max and $maxphp are in Kb + $maxphp2=@ini_get('post_max_size'); // In unknown + if (preg_match('/k$/i', $maxphp2)) $maxphp2=$maxphp2*1; + if (preg_match('/m$/i', $maxphp2)) $maxphp2=$maxphp2*1024; + if (preg_match('/g$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024; + if (preg_match('/t$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024*1024; + // Now $max and $maxphp and $maxphp2 are in Kb $maxmin = $max; - if ($maxphp > 0) $maxmin=min($max, $maxphp); + $maxphptoshow = $maxphptoshowparam = ''; + if ($maxphp > 0) + { + $maxmin=min($max, $maxphp); + $maxphptoshow = $maxphp; + $maxphptoshowparam = 'upload_max_filesize'; + } + if ($maxphp2 > 0) + { + $maxmin=min($max, $maxphp2); + if ($maxphp2 < $maxphp) + { + $maxphptoshow = $maxphp2; + $maxphptoshowparam = 'post_max_size'; + } + } if ($maxmin > 0) { @@ -168,7 +188,7 @@ class FormFile { $langs->load('other'); $out .= ' '; - $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphp), 1); + $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow), 1); } } else diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 6f712fa6c4d..a7797f91833 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -733,40 +733,97 @@ class FormTicket print ajax_combobox('select'.$htmlname); } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Clear list of attached files in send mail form (also stored in session) + * + * @return void + */ + public function clear_attached_files() + { + // phpcs:enable + global $conf,$user; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path + if (is_dir($upload_dir)) dol_delete_dir_recursive($upload_dir); + + $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined + unset($_SESSION["listofpaths".$keytoavoidconflict]); + unset($_SESSION["listofnames".$keytoavoidconflict]); + unset($_SESSION["listofmimes".$keytoavoidconflict]); + } + /** * Show the form to add message on ticket * - * @param string $width Width of form - * @return void + * @param string $width Width of form + * @return void */ public function showMessageForm($width = '40%') { - global $conf, $langs, $user, $mysoc; + global $conf, $langs, $user, $hookmanager, $form, $mysoc; + + $formmail = new FormMail($this->db); + $addfileaction = 'addfile'; + + if (! is_object($form)) $form=new Form($this->db); // Load translation files required by the page $langs->loadLangs(array('other', 'mails')); - $addfileaction = 'addfile'; + // Clear temp files. Must be done at beginning, before call of triggers + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) + { + $this->clear_attached_files(); + } - $form = new Form($this->db); - $formmail = new FormMail($this->db); + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $this->param['langsmodels']; + if (! empty($newlang)) + { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('other'); + } + // Get message template for $this->param["models"] into c_email_templates + $arraydefaultmessage = -1; + if ($this->param['models'] != 'none') + { + $model_id=0; + if (array_key_exists('models_id', $this->param)) + { + $model_id=$this->param["models_id"]; + } + + $arraydefaultmessage=$formmail->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id); // If $model_id is empty, preselect the first one + } // Define list of attached files $listofpaths = array(); $listofnames = array(); $listofmimes = array(); - if (!empty($_SESSION["listofpaths"])) { - $listofpaths = explode(';', $_SESSION["listofpaths"]); + $keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined + + if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) + { + if (! empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit'])) + { + foreach($this->param['fileinit'] as $file) + { + $this->add_attached_files($file, basename($file), dol_mimetype($file)); + } + } } - if (!empty($_SESSION["listofnames"])) { - $listofnames = explode(';', $_SESSION["listofnames"]); - } - - if (!empty($_SESSION["listofmimes"])) { - $listofmimes = explode(';', $_SESSION["listofmimes"]); - } + if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';', $_SESSION["listofpaths".$keytoavoidconflict]); + if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';', $_SESSION["listofnames".$keytoavoidconflict]); + if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';', $_SESSION["listofmimes".$keytoavoidconflict]); // Define output language $outputlangs = $langs; @@ -808,6 +865,7 @@ class FormTicket print '
'; print ''; print ''; + print ''; foreach ($this->param as $key => $value) { print ''; } @@ -1000,7 +1058,7 @@ class FormTicket $out .= '
'; $out .= img_mime($listofnames[$key]) . ' ' . $listofnames[$key]; if (!$this->withfilereadonly) { - $out .= ' '; + $out .= ' '; } $out .= '
'; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c930dbf172a..9aa6177adf4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2935,22 +2935,23 @@ function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF /** * Show picto whatever it's its name (generic function) * - * @param string $titlealt Text on title tag for tooltip. Not used if param notitle is set to 1. - * @param string $picto Name of image file to show ('filenew', ...) - * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. - * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img - * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img - * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) - * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') - * @param boolean|int $pictoisfullpath If true or 1, image path is a full path - * @param int $srconly Return only content of the src attribute of img. - * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. - * @param string $alt Force alt for bind people - * @param string $morecss Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty. - * @return string Return img tag + * @param string $titlealt Text on title tag for tooltip. Not used if param notitle is set to 1. + * @param string $picto Name of image file to show ('filenew', ...) + * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. + * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img + * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img + * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) + * @param string $moreatt Add more attribute on img tag (For example 'style="float: right"') + * @param boolean|int $pictoisfullpath If true or 1, image path is a full path + * @param int $srconly Return only content of the src attribute of img. + * @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip. + * @param string $alt Force alt for bind people + * @param string $morecss Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty. + * @param string $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left maring on picto, 0 = No margin left. Works for fontawesome picto only. + * @return string Return img tag * @see img_object(), img_picto_common() */ -function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly = 0, $notitle = 0, $alt = '', $morecss = '') +function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $srconly = 0, $notitle = 0, $alt = '', $morecss = '', $marginleftonlyshort = 2) { global $conf, $langs; @@ -2986,7 +2987,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fa='fas'; $fakey = $pictowithoutext; $facolor = ''; $fasize = ''; - $marginleftonlyshort = 2; + if ($pictowithoutext == 'setup') { $fakey = 'fa-cog'; $fasize = '1.4em'; diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index 9e0c357be05..84be86f4a15 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -185,5 +185,5 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ print '
'; } - print '
'; + print '
'; } diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index 9f481b6b648..cc2bf4cea26 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -35,6 +35,8 @@ $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; $langs->load("interventions"); +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); + $ilink=0; foreach($linkedObjectBlock as $key => $objectlink) { diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 7bcd69e3d0b..2d3882e523e 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -567,25 +567,46 @@ if ($step == 3 && $datatoimport) //print '
'.$langs->trans("FileWithDataToImport").'
'; - print '     '; + print '
'; + print '     '; $out = (empty($conf->global->MAIN_UPLOAD_DOC)?' disabled':''); print ''; $out=''; if (! empty($conf->global->MAIN_UPLOAD_DOC)) { - $max=$conf->global->MAIN_UPLOAD_DOC; // En Kb - $maxphp=@ini_get('upload_max_filesize'); // En inconnu - if (preg_match('/k$/i', $maxphp)) $maxphp=$maxphp*1; - if (preg_match('/m$/i', $maxphp)) $maxphp=$maxphp*1024; - if (preg_match('/g$/i', $maxphp)) $maxphp=$maxphp*1024*1024; - if (preg_match('/t$/i', $maxphp)) $maxphp=$maxphp*1024*1024*1024; - // Now $max and $maxphp are in Kb - if ($maxphp > 0) $max=min($max, $maxphp); + $max=$conf->global->MAIN_UPLOAD_DOC; // In Kb + $maxphp=@ini_get('upload_max_filesize'); // In unknown + if (preg_match('/k$/i', $maxphp)) $maxphp=$maxphp*1; + if (preg_match('/m$/i', $maxphp)) $maxphp=$maxphp*1024; + if (preg_match('/g$/i', $maxphp)) $maxphp=$maxphp*1024*1024; + if (preg_match('/t$/i', $maxphp)) $maxphp=$maxphp*1024*1024*1024; + $maxphp2=@ini_get('post_max_size'); // In unknown + if (preg_match('/k$/i', $maxphp2)) $maxphp2=$maxphp2*1; + if (preg_match('/m$/i', $maxphp2)) $maxphp2=$maxphp2*1024; + if (preg_match('/g$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024; + if (preg_match('/t$/i', $maxphp2)) $maxphp2=$maxphp2*1024*1024*1024; + // Now $max and $maxphp and $maxphp2 are in Kb + $maxmin = $max; + $maxphptoshow = $maxphptoshowparam = ''; + if ($maxphp > 0) + { + $maxmin=min($max, $maxphp); + $maxphptoshow = $maxphp; + $maxphptoshowparam = 'upload_max_filesize'; + } + if ($maxphp2 > 0) + { + $maxmin=min($max, $maxphp2); + if ($maxphp2 < $maxphp) + { + $maxphptoshow = $maxphp2; + $maxphptoshowparam = 'post_max_size'; + } + } $langs->load('other'); $out .= ' '; - $out.=info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphp), 1); + $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow), 1); } else { @@ -846,7 +867,7 @@ if ($step == 4 && $datatoimport) print ''; print '
'; - print $langs->trans("SelectImportFields", img_picto('', 'grip_title', '')).' '; + print $langs->trans("SelectImportFields", img_picto('', 'grip_title', '', false, 0, 0, '', '', 0)).' '; $htmlother->select_import_model($importmodelid, 'importmodelid', $datatoimport, 1); print ''; print '
'; diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 3bc705c7a19..aaa96e3136a 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -102,9 +102,9 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_PAYED','Expense report billed','Executed when an expense report is set as billed','expensereport',204); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',204); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',205); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',211); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',212); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_VALIDATE','Project validation','Executed when a project is validated','project',141); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',143); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TICKET_CREATE','Ticket created','Executed when a ticket is created','ticket',161); @@ -116,7 +116,7 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value -- actions not enabled by default (no constant created for that) when we enable module agenda insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_MODIFY','Product or service modified','Executed when a product or sevice is modified','product',41); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_MODIFY','Member modified','Executed when a member is modified','member',23); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_MODIFY','Intervention modified','Executed when a intervention is modified','ficheinter',31); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_MODIFY','Intervention modified','Executed when a intervention is modified','ficheinter',19); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_CREATE','Project creation','Executed when a project is created','project',140); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_MODIFY','Project modified','Executed when a project is modified','project',142); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index bb92e41a537..8e4d42559a8 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -219,6 +219,7 @@ ErrorURLMustStartWithHttp=URL %s must start with http:// or https:// ErrorNewRefIsAlreadyUsed=Error, the new reference is already used ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible=Error, delete payment linked to a closed invoice is not possible. # Warnings +WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. WarningMandatorySetupNotComplete=Click here to setup mandatory parameters WarningEnableYourModulesApplications=Click here to enable your modules and applications diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 6efbe942032..5e55597c306 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -759,6 +759,7 @@ LinkToSupplierProposal=Link to vendor proposal LinkToSupplierInvoice=Link to vendor invoice LinkToContract=Link to contract LinkToIntervention=Link to intervention +LinkToTicket=Link to ticket CreateDraft=Create draft SetToDraft=Back to draft ClickToEdit=Click to edit diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 46555a84528..36ca0ede002 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -2,6 +2,7 @@ ProductRef=Product ref. ProductLabel=Product label ProductLabelTranslated=Translated product label +ProductDescription=Product description ProductDescriptionTranslated=Translated product description ProductNoteTranslated=Translated product note ProductServiceCard=Products/Services card diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index ee2b14fdf11..6f51078fc8c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -351,7 +351,7 @@ if (! defined('NOTOKENRENEWAL')) } //var_dump(GETPOST('token').' '.$_SESSION['token'].' - '.$_SESSION['newtoken'].' '.$_SERVER['SCRIPT_FILENAME']); - +//$dolibarr_nocsrfcheck=1; // Check token //var_dump((! defined('NOCSRFCHECK')).' '.empty($dolibarr_nocsrfcheck).' '.(! empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)).' '.$_SERVER['REQUEST_METHOD'].' '.(! GETPOSTISSET('token'))); if ((! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && ! empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index b663aaa43c3..b7d17244c2a 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -17,7 +17,7 @@ */ /** - * \file htdocs/public/ticket/index.php + * \file htdocs/public/ticket/create_ticket.php * \ingroup ticket * \brief Display public form to add new ticket */ diff --git a/htdocs/public/ticket/index.php b/htdocs/public/ticket/index.php index 2e138312102..b7f7bd71088 100644 --- a/htdocs/public/ticket/index.php +++ b/htdocs/public/ticket/index.php @@ -77,7 +77,7 @@ print ''; print ''; // End of page -htmlPrintOnlinePaymentFooter($mysoc, $langs, 1, $suffix, $object); +htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); llxFooter('', 'public'); diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 9da0a4272e1..5e1ce07e098 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -210,7 +210,8 @@ if ($action == "view_ticketlist") '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.track_id' => array('label' => $langs->trans("IDTracking"), 'checked' => 0), + '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), @@ -218,7 +219,7 @@ if ($action == "view_ticketlist") '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.fk_user_assign' => array('label' => $langs->trans("AssignedTo"), '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), @@ -236,37 +237,37 @@ if ($action == "view_ticketlist") } if (!empty($search_subject)) { $filter['t.subject'] = $search_subject; - $param .= '&search_subject=' . $search_subject; + $param .= '&search_subject=' .urlencode($search_subject); } if (!empty($search_type)) { $filter['t.type_code'] = $search_type; - $param .= '&search_type=' . $search_type; + $param .= '&search_type=' . urlencode($search_type); } if (!empty($search_category)) { $filter['t.category_code'] = $search_category; - $param .= '&search_category=' . $search_category; + $param .= '&search_category=' . urlencode($search_category); } if (!empty($search_severity)) { $filter['t.severity_code'] = $search_severity; - $param .= '&search_severity=' . $search_severity; + $param .= '&search_severity=' . urlencode($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; + $param .= '&search_fk_user_assign=' . urlencode($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; + $param .= '&search_fk_user_create=' . urlencode($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; + $param .= '&search_fk_status=' . urlencode($search_fk_status); } if (isset($search_fk_status) && $search_fk_status == 'non_closed') { $filter['t.fk_statut'] = array(0, 1, 3, 4, 5, 6); @@ -387,62 +388,7 @@ if ($action == "view_ticketlist") print ''; - print ''; - 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.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->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['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); - } - } - } - 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); - } - print_liste_field_titre($selectedfields, $url_page_current, "", '', '', 'align="right"', $sortfield, $sortorder, 'maxwidthsearch '); - print ''; - - /* - * Filter bar - */ - + // Filter bar print ''; if (!empty($arrayfields['t.datec']['checked'])) { @@ -462,13 +408,13 @@ if ($action == "view_ticketlist") if (!empty($arrayfields['t.subject']['checked'])) { print ''; } if (!empty($arrayfields['type.code']['checked'])) { print ''; } @@ -523,6 +469,59 @@ if ($action == "view_ticketlist") print ''; print ''; + // Field title + print ''; + 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.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->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['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); + } + } + } + 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); + } + print_liste_field_titre($selectedfields, $url_page_current, "", '', '', 'align="right"', $sortfield, $sortorder, 'maxwidthsearch '); + print ''; + while ($obj = $db->fetch_object($resql)) { print ''; @@ -550,7 +549,7 @@ if ($action == "view_ticketlist") // Ref if (!empty($arrayfields['t.ref']['checked'])) { - print ''; } @@ -612,8 +611,6 @@ if ($action == "view_ticketlist") $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($langs); - } else { - print $langs->trans('None'); } print ''; } @@ -705,7 +702,7 @@ if ($action == "view_ticketlist") print ""; // End of page -htmlPrintOnlinePaymentFooter($mysoc, $langs, 1, $suffix, $object); +htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); llxFooter('', 'public'); diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php index 69a77413b2e..cdbd3abad19 100644 --- a/htdocs/public/ticket/view.php +++ b/htdocs/public/ticket/view.php @@ -17,7 +17,7 @@ */ /** - * \file htdocs/public/ticket/index.php + * \file htdocs/public/ticket/view.php * \ingroup ticket * \brief Public file to add and manage ticket */ @@ -48,8 +48,9 @@ $langs->loadLangs(array("companies","other","ticket")); // Get parameters $track_id = GETPOST('track_id', 'alpha'); -$action = GETPOST('action', 'aZ09'); -$email = GETPOST('email', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$email = GETPOST('email', 'alpha'); if (GETPOST('btn_view_ticket')) { unset($_SESSION['email_customer']); @@ -65,7 +66,17 @@ $object = new ActionsTicket($db); * Actions */ -if ($action == "view_ticket" || $action == "add_message" || $action == "close" || $action == "confirm_public_close" || $action == "new_public_message") { +if ($cancel) +{ + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action='view_ticket'; +} + +if ($action == "view_ticket" || $action == "presend" || $action == "close" || $action == "confirm_public_close" || $action == "add_message") { $error = 0; $display_ticket = false; if (!strlen($track_id)) { @@ -73,7 +84,6 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | 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"))); @@ -89,25 +99,52 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | 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) { + // Check if emails provided is the one of author + if ($object->dao->origin_email == $email) + { + $display_ticket = true; + $_SESSION['email_customer'] = $email; + } + // Check if emails provided is inside list of contacts + else { + $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; + } + } + } + // Check email of thirdparty of ticket + if ($object->dao->fk_soc > 0 || $object->dao->socid > 0) { $object->dao->fetch_thirdparty(); + if ($email == $object->dao->thirdparty->email) { + $display_ticket = true; + $_SESSION['email_customer'] = $email; + } } - - if ($email == $object->dao->origin_email || $email == $object->dao->thirdparty->email) { - $display_ticket = true; - $_SESSION['email_customer'] = $email; + // Check if email is email of creator + if ($object->dao->fk_user_create > 0) + { + $tmpuser = new User($db); + $tmpuser->fetch($object->dao->fk_user_create); + if ($email == $tmpuser->email) { + $display_ticket = true; + $_SESSION['email_customer'] = $email; + } + } + // Check if email is email of creator + if ($object->dao->fk_user_assign > 0 && $object->dao->fk_user_assign != $object->dao->fk_user_create) + { + $tmpuser = new User($db); + $tmpuser->fetch($object->dao->fk_user_assign); + if ($email == $tmpuser->email) { + $display_ticket = true; + $_SESSION['email_customer'] = $email; + } } } else { $error++; @@ -116,14 +153,56 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | } } + if (! $error && $action == 'confirm_public_close' && $display_ticket) + { + if ($object->dao->close($user)) { + setEventMessages($langs->trans('TicketMarkedAsClosed'), null, 'mesgs'); + + $url = 'view.php?action=view_ticket&track_id=' . GETPOST('track_id', 'alpha'); + header("Location: " . $url); + } else { + $action = ''; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + if (! $error && $action == "add_message" && $display_ticket && GETPOSTISSET('btn_add_message')) + { + // TODO Add message... + $ret = $object->dao->newMessage($user, $action, 0); + + + + + + if (! $error) + { + $action = 'view_ticket'; + } + } + if ($error || $errors) { setEventMessages($object->error, $object->errors, 'errors'); - $action = ''; + if ($action == "add_message") + { + $action = 'presend'; + } + else + { + $action = ''; + } } } - +//var_dump($action); //$object->doActions($action); +// Actions to send emails (for ticket, we need to manage the addfile and removefile only) +$trigger_name='TICKET_SENTBYMAIL'; +$paramname='id'; +$autocopy='MAIN_MAIL_AUTOCOPY_TICKET_TO'; // used to know the automatic BCC to add +$trackid='tic'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + /* @@ -144,13 +223,13 @@ $arrayofcss = array('/ticket/css/styles.css.php'); llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss); -print '
'; +print '
'; -if ($action == "view_ticket" || $action == "add_message" || $action == "close" || $action == "confirm_public_close") { +if ($action == "view_ticket" || $action == "presend" || $action == "close" || $action == "confirm_public_close") { if ($display_ticket) { // Confirmation close if ($action == 'close') { - print $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1); } print '
'; @@ -230,8 +309,6 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | $fuser = new User($db); $fuser->fetch($object->dao->fk_user_assign); print $fuser->getFullName($langs, 1); - } else { - print $langs->trans('None'); } print '
'; @@ -246,21 +323,25 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | print '
'; - if ($action == 'add_message') { + if ($action == 'presend') { print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticket'); $formticket = new FormTicket($db); - $formticket->action = "new_public_message"; + $formticket->action = "add_message"; $formticket->track_id = $object->dao->track_id; $formticket->id = $object->dao->id; - $formticket->param = array('fk_user_create' => '-1'); + $formticket->param = array('track_id' => $object->dao->track_id, 'fk_user_create' => '-1', 'returnurl' => DOL_URL_ROOT.'/public/ticket/view.php'); $formticket->withfile = 2; + $formticket->withcancel = 1; + $formticket->showMessageForm('100%'); - } else { - print ''; + } + + if ($action != 'presend') { + print ''; print ''; print ''; print ''; @@ -269,15 +350,16 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | print "\n"; print '
'; - // List ticket - print ''; - if ($object->dao->fk_statut < 8) { + // List ticket + print ''; + + if ($object->dao->fk_statut < Ticket::STATUS_CLOSED) { // New message - print ''; + print ''; // Close ticket - if ($object->dao->fk_statut > 0 && $object->dao->fk_statut < 8) { + if ($object->dao->fk_statut >= Ticket::STATUS_NOT_READ && $object->dao->fk_statut < Ticket::STATUS_CLOSED) { print ''; } } @@ -287,13 +369,7 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | // Message list print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticket'); - $object->viewTicketMessages(false); - - print '
'; - - // Logs list - print load_fiche_titre($langs->trans('TicketHistory'), '', 'history@ticket'); - $object->viewTicketLogs(false); + $object->viewTicketMessages(false, true, $object->dao); } else { print ''; } @@ -324,7 +400,7 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" | print "
"; // End of page -htmlPrintOnlinePaymentFooter($mysoc, $langs, 1, $suffix, $object); +htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); llxFooter('', 'public'); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 7fb121fd90c..f33ede5ba4c 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5251,10 +5251,26 @@ div.tabsElem a.tab { /* ============================================================================== */ /* Ticket module */ /* ============================================================================== */ - +.ticketpublicarea { + width: 70%; +} .publicnewticketform { margin-top: 25px !important; } +.ticketlargemargin { + padding-left: 50px; + padding-right: 50px; +} +@media only screen and (max-width: 767px) +{ + .ticketlargemargin { + padding-left: 5px; padding-right: 5px; + } + .ticketpublicarea { + width: 100%; + } +} + #cd-timeline { position: relative; padding: 2em 0; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c15bbf26eef..9fad375eade 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -5404,9 +5404,25 @@ border-top-right-radius: 6px; /* Ticket module */ /* ============================================================================== */ +.ticketpublicarea { + width: 70%; +} .publicnewticketform { margin-top: 25px !important; } +.ticketlargemargin { + padding-left: 50px; + padding-right: 50px; +} +@media only screen and (max-width: 767px) +{ + .ticketlargemargin { + padding-left: 5px; padding-right: 5px; + } + .ticketpublicarea { + width: 100%; + } +} #cd-timeline { position: relative; diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 94c0aec8d90..b770e2fec40 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -75,7 +75,7 @@ if (empty($action) && empty($id) && empty($ref)) $action='view'; //Select mail models is same action as add_message if (GETPOST('modelselected', 'alpha')) { - $action = 'create_message'; + $action = 'presend'; } // Load object @@ -255,17 +255,17 @@ if (GETPOST('add', 'alpha') && $user->rights->ticket->write) { if ($action == 'edit' && $user->rights->ticket->write) { $error = 0; - if ($object->fetch(GETPOST('id')) < 0) { + if ($object->fetch(GETPOST('id', 'int')) < 0) { $error++; array_push($object->errors, $langs->trans("ErrorTicketIsNotValid")); $_GET["action"] = $_POST["action"] = ''; } } -if (GETPOST('update') && GETPOST('id') && $user->rights->ticket->write) { +if (GETPOST('update', 'alpha') && GETPOST('id', 'int') && $user->rights->ticket->write) { $error = 0; - $ret = $object->fetch(GETPOST('id')); + $ret = $object->fetch(GETPOST('id', 'int')); if ($ret < 0) { $error++; array_push($object->errors, $langs->trans("ErrorTicketIsNotValid")); @@ -385,7 +385,7 @@ if ($action == "add_message" && GETPOST('btn_add_message') && $user->rights->tic exit; } else { setEventMessages($object->error, null, 'errors'); - $action = 'create_message'; + $action = 'presend'; } } @@ -394,9 +394,6 @@ if ($action == "confirm_close" && GETPOST('confirm', 'alpha') == 'yes' && $user- $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')); if ($object->close($user)) { - // Log action in ticket logs table - $log_action = $langs->trans('TicketLogClosedBy', $user->getFullName($langs)); - setEventMessages($langs->trans('TicketMarkedAsClosed'), null, 'mesgs'); $url = 'card.php?action=view&track_id=' . GETPOST('track_id', 'alpha'); @@ -409,13 +406,15 @@ if ($action == "confirm_close" && GETPOST('confirm', 'alpha') == 'yes' && $user- if ($action == "confirm_public_close" && GETPOST('confirm', 'alpha') == 'yes') { $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')); - if (($_SESSION['email_customer'] == $object->origin_email || $_SESSION['email_customer'] == $object->thirdparty->email) && $object->close()) { + if ($_SESSION['email_customer'] == $object->origin_email || $_SESSION['email_customer'] == $object->thirdparty->email) { + $object->close($user); + // Log action in ticket logs table $log_action = $langs->trans('TicketLogClosedBy', $_SESSION['email_customer']); setEventMessages('
' . $langs->trans('TicketMarkedAsClosed') . '
', null, 'mesgs'); - $url = 'view.php?action=view_ticket&track_id=' . GETPOST('track_id', 'alpha'); + $url = 'card.php?action=view_ticket&track_id=' . GETPOST('track_id', 'alpha'); header("Location: " . $url); } else { setEventMessages($object->error, $object->errors, 'errors'); @@ -477,7 +476,6 @@ if ($action == 'setsubject') { } } - if ($action == 'confirm_reopen' && $user->rights->ticket->manage && !GETPOST('cancel')) { if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) { // prevent browser refresh from reopening ticket several times @@ -601,6 +599,8 @@ $autocopy='MAIN_MAIL_AUTOCOPY_TICKET_TO'; // used to know the automatic BCC to $trackid='tic'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; +// Set $action to correct value for the case we used presend action to add a message +if (GETPOSTISSET('actionbis') && $action == 'presend') $action = 'presend_addmessage'; /* @@ -640,7 +640,7 @@ if ($action == 'create' || $action == 'presend') $formticket->showForm(1); } -if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'create_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' +if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' || $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') { if ($res > 0) @@ -824,9 +824,11 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd dol_banner_tab($object, 'ref', $linkback, ($user->societe_id ? 0 : 1), 'ref', 'ref', $morehtmlref); - print '
'; + print '
'; + print '
'; print '
'; - print '
'; - print ''; + print ''; print ''; - $formTicket->selectTypesTickets($search_type, 'search_type', '', 2, 1, 1); + $formTicket->selectTypesTickets($search_type, 'search_type', '', 2, 1, 1, 0, 'maxwidth150'); print '
'; + print ''; print $obj->ref; print '
'; + + print '
'; // Track ID print ''; // Group print ''; // Severity print ''; } print '
' . $langs->trans("TicketTrackId") . ''; @@ -956,7 +958,6 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd // View Original message $actionobject->viewTicketOriginalMessage($user, $action, $object); - // Classification of ticket print '
'; print ''; @@ -1011,29 +1012,20 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd // Type print '
' . $langs->trans("Type") . ''; print $langs->getLabelFromKey($db, $object->type_code, 'c_ticket_type', 'code', 'label'); - /*if ($user->admin && !$noadmininfo) { - print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); - }*/ print '
' . $langs->trans("TicketGroup") . ''; print $langs->getLabelFromKey($db, $object->category_code, 'c_ticket_category', 'code', 'label'); - /*if ($user->admin && !$noadmininfo) { - print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); - }*/ print '
' . $langs->trans("TicketSeverity") . ''; print $langs->getLabelFromKey($db, $object->severity_code, 'c_ticket_severity', 'code', 'label'); - /*if ($user->admin && !$noadmininfo) { - print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); - }*/ print '
'; // End table actions + print ''; print ''; - print ''; // Display navbar with links to change ticket status print ''; @@ -1163,7 +1155,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd // Buttons for actions - if ($action != 'presend' && $action != 'editline') { + if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'editline') { print '
'."\n"; $parameters=array(); $reshook=$hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook @@ -1172,8 +1164,8 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd if (empty($reshook)) { // Show link to add a message (if read and not closed) - if ($object->fk_statut < Ticket::STATUS_CLOSED && $action != "create_message") { - print ''; + if ($object->fk_statut < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") { + print ''; } // Link to create an intervention @@ -1208,8 +1200,10 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd if (GETPOST('modelselected')) { $action = 'presend'; } + // Set $action to correct value for the case we used presend action to add a message + if (GETPOSTISSET('actionbis') && $action == 'presend') $action = 'presend_addmessage'; - if ($action != 'create_message') + if ($action != 'presend' && $action != 'presend_addmessage') { print '
'; print ''; // ancre @@ -1225,9 +1219,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'ticket', $socid, 1); - print '
'; - print '
'; - print '
'; + print ''; } else { @@ -1243,23 +1235,23 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd $substitutionarray['__THIRDPARTY_NAME__'] = $object->thirdparty->name; } $substitutionarray['__SIGNATURE__'] = $user->signature; - $substitutionarray['__TICKETSUP_TRACKID__'] = $object->track_id; - $substitutionarray['__TICKETSUP_REF__'] = $object->ref; - $substitutionarray['__TICKETSUP_SUBJECT__'] = $object->subject; - $substitutionarray['__TICKETSUP_TYPE__'] = $object->type_code; - $substitutionarray['__TICKETSUP_SEVERITY__'] = $object->severity_code; - $substitutionarray['__TICKETSUP_CATEGORY__'] = $object->category_code; // For backward compatibility - $substitutionarray['__TICKETSUP_ANALYTIC_CODE__'] = $object->category_code; - $substitutionarray['__TICKETSUP_MESSAGE__'] = $object->message; - $substitutionarray['__TICKETSUP_PROGRESSION__'] = $object->progress; + $substitutionarray['__TICKET_TRACKID__'] = $object->track_id; + $substitutionarray['__TICKET_REF__'] = $object->ref; + $substitutionarray['__TICKET_SUBJECT__'] = $object->subject; + $substitutionarray['__TICKET_TYPE__'] = $object->type_code; + $substitutionarray['__TICKET_SEVERITY__'] = $object->severity_code; + $substitutionarray['__TICKET_CATEGORY__'] = $object->category_code; // For backward compatibility + $substitutionarray['__TICKET_ANALYTIC_CODE__'] = $object->category_code; + $substitutionarray['__TICKET_MESSAGE__'] = $object->message; + $substitutionarray['__TICKET_PROGRESSION__'] = $object->progress; if ($object->fk_user_assign > 0) { $userstat->fetch($object->fk_user_assign); - $substitutionarray['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); + $substitutionarray['__TICKET_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); } if ($object->fk_user_create > 0) { $userstat->fetch($object->fk_user_create); - $substitutionarray['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); + $substitutionarray['__TICKET_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); } foreach ($substitutionarray as $key => $val) { $help.=$key.' -> '.$langs->trans($val).'
'; diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php index b10f8ebe7da..3e9daabec75 100644 --- a/htdocs/ticket/class/actions_ticket.class.php +++ b/htdocs/ticket/class/actions_ticket.class.php @@ -167,72 +167,12 @@ class ActionsTicket } } - /** - * View html list of logs - * - * @param boolean $show_user Show user who make action - * @return void - */ - public function viewTicketLogs($show_user = true) - { - global $conf, $langs; - - // Load logs in cache - $ret = $this->dao->loadCacheLogsTicket(); - - if (is_array($this->dao->cache_logs_ticket) && count($this->dao->cache_logs_ticket) > 0) { - print ''; - - print ''; - - print ''; - - if ($show_user) { - print ''; - } - - foreach ($this->dao->cache_logs_ticket as $id => $arraylogs) { - print ''; - print ''; - - if ($show_user) { - print ''; - } - print ''; - print ''; - print ''; - print ''; - } - - print '
'; - print $langs->trans('DateCreation'); - print ''; - print $langs->trans('User'); - print '
'; - print dol_print_date($arraylogs['datec'], 'dayhour'); - print ''; - if ($arraylogs['fk_user_create'] > 0) { - $userstat = new User($this->db); - $res = $userstat->fetch($arraylogs['fk_user_create']); - if ($res) { - print $userstat->getNomUrl(1); - } - } - print '
'; - print dol_nl2br($arraylogs['message']); - - print '
'; - } else { - print '
' . $langs->trans('NoLogForThisTicket') . '
'; - } - } - /** * Show ticket original message * * @param User $user User wich display * @param string $action Action mode - * @param Ticket $object Object ticket + * @param Ticket $object Object ticket * @return void */ public function viewTicketOriginalMessage($user, $action, $object) @@ -280,7 +220,7 @@ class ActionsTicket //print '
' . $object->message . '
'; } - if ($user->rights->ticket->manage && $action == 'edit_message_init') { + if (!empty($user->rights->ticket->manage) && $action == 'edit_message_init') { print '
'; print ' '; print ' '; @@ -289,33 +229,42 @@ class ActionsTicket print '
'; + print ''; + + if (!empty($user->rights->ticket->manage) && $action == 'edit_message_init') { + // MESSAGE + print ''; + } } + /** * View html list of message for ticket * - * @param boolean $show_private Show private messages - * @param boolean $show_user Show user who make action - * @return void + * @param boolean $show_private Show private messages + * @param boolean $show_user Show user who make action + * @param Ticket $object Object ticket + * @return void */ - public function viewTicketMessages($show_private, $show_user = true) + public function viewTicketMessages($show_private, $show_user, $object) { global $conf, $langs, $user; // Load logs in cache $ret = $this->dao->loadCacheMsgsTicket(); - $action = GETPOST('action'); + if ($ret < 0) dol_print_error($this->dao->db); - $this->viewTicketOriginalMessage($user, $action); + $action = GETPOST('action', 'alpha'); - if (is_array($this->dao->cache_msgs_ticket) && count($this->dao->cache_msgs_ticket) > 0) { - print load_fiche_titre($langs->trans('TicketMailExchanges')); + $this->viewTicketOriginalMessage($user, $action, $object); + if (is_array($this->dao->cache_msgs_ticket) && count($this->dao->cache_msgs_ticket) > 0) + { print ''; print ''; print ''; if ($show_user) { @@ -335,9 +284,9 @@ class ActionsTicket print ''; if ($show_user) { print '
'; - print $langs->trans('DateCreation'); + print $langs->trans('TicketMessagesList'); print ''; - if ($arraymsgs['fk_user_action'] > 0) { + if ($arraymsgs['fk_user_author'] > 0) { $userstat = new User($this->db); - $res = $userstat->fetch($arraymsgs['fk_user_action']); + $res = $userstat->fetch($arraymsgs['fk_user_author']); if ($res) { print $userstat->getNomUrl(0); } diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index bb5f673d57e..60b3927a09a 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -180,10 +180,10 @@ class Ticket extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'position'=>1, 'visible'=>-2, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id"), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>5, 'notnull'=>1, 'index'=>1), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'css'=>''), - 'track_id' => array('type'=>'varchar(255)', 'label'=>'TrackID', 'visible'=>0, 'enabled'=>1, 'position'=>11, 'notnull'=>-1, 'searchall'=>1, 'help'=>"Help text"), + 'track_id' => array('type'=>'varchar(255)', 'label'=>'TicketTrackId', 'visible'=>-2, 'enabled'=>1, 'position'=>11, 'notnull'=>-1, 'searchall'=>1, 'help'=>"Help text"), 'fk_user_create' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Author', 'visible'=>1, 'enabled'=>1, 'position'=>15, 'notnull'=>1, 'css'=>'nowraponall'), 'origin_email' => array('type'=>'mail', 'label'=>'OriginEmail', 'visible'=>-2, 'enabled'=>1, 'position'=>16, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object"), - 'subject' => array('type'=>'varchar(255)', 'label'=>'Subject', 'visible'=>1, 'enabled'=>1, 'position'=>18, 'notnull'=>-1, 'searchall'=>1, 'help'=>""), + 'subject' => array('type'=>'varchar(255)', 'label'=>'Subject', 'visible'=>1, 'enabled'=>1, 'position'=>18, 'notnull'=>-1, 'searchall'=>1, 'help'=>"", 'css'=>'maxwidth75'), 'type_code' => array('type'=>'varchar(32)', 'label'=>'Type', 'visible'=>1, 'enabled'=>1, 'position'=>20, 'notnull'=>-1, 'searchall'=>1, 'help'=>"", 'css'=>'maxwidth100'), 'category_code' => array('type'=>'varchar(32)', 'label'=>'TicketGroup', 'visible'=>-1, 'enabled'=>1, 'position'=>21, 'notnull'=>-1, 'help'=>"", 'css'=>'maxwidth100'), 'severity_code' => array('type'=>'varchar(32)', 'label'=>'Severity', 'visible'=>1, 'enabled'=>1, 'position'=>22, 'notnull'=>-1, 'help'=>"", 'css'=>'maxwidth100'), @@ -1660,20 +1660,19 @@ class Ticket extends CommonObject } /** - * Charge la liste des messages sur le ticket + * Load the list of event on ticket into ->cache_msgs_ticket * * @return int Number of lines loaded, 0 if already loaded, <0 if KO */ public function loadCacheMsgsTicket() { - global $langs; - if (is_array($this->cache_msgs_ticket) && count($this->cache_msgs_ticket)) { return 0; } - // Cache deja charge - $sql = "SELECT rowid, fk_user_author, datec, label, message, visibility"; + // Cache already loaded + + $sql = "SELECT id as rowid, fk_user_author, datec, label, note as message, visibility"; $sql .= " FROM " . MAIN_DB_PREFIX . "actioncomm"; $sql .= " WHERE fk_element = " . (int) $this->id; $sql .= " AND elementtype = 'ticket'"; @@ -1687,7 +1686,7 @@ class Ticket extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); $this->cache_msgs_ticket[$i]['id'] = $obj->rowid; - $this->cache_msgs_ticket[$i]['fk_user_action'] = $obj->fk_user_action; + $this->cache_msgs_ticket[$i]['fk_user_author'] = $obj->fk_user_author; $this->cache_msgs_ticket[$i]['datec'] = $this->db->jdate($obj->datec); $this->cache_msgs_ticket[$i]['subject'] = $obj->label; $this->cache_msgs_ticket[$i]['message'] = $obj->message; diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 91eeceb54e4..0f415ddbf33 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -499,10 +499,11 @@ print ''; foreach($object->fields as $key => $val) { - $cssforfield=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; - if (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; - if ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center'; + $cssforfield=(empty($val['css'])?'':$val['css']); + if ($key == 'fk_statut') $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price'))) $cssforfield.=($cssforfield?' ':'').'right'; if (! empty($arrayfields['t.'.$key]['checked'])) { if ($key == 'type_code') { print ''."\n"; print ''; foreach($object->fields as $key => $val) { - $cssforfield=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; - if (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; + $cssforfield=(empty($val['css'])?'':$val['css']); if ($key == 'fk_statut') $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price'))) $cssforfield.=($cssforfield?' ':'').'right'; if (! empty($arrayfields['t.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, '', $sortfield, $sortorder, ($cssforfield?$cssforfield.' ':''))."\n"; diff --git a/htdocs/ticket/tpl/linkedobjectblock.tpl.php b/htdocs/ticket/tpl/linkedobjectblock.tpl.php index 3391437dbb1..8aed516e4fc 100644 --- a/htdocs/ticket/tpl/linkedobjectblock.tpl.php +++ b/htdocs/ticket/tpl/linkedobjectblock.tpl.php @@ -13,8 +13,7 @@ * 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. + * along with this program. If not, see . */ // Protection to avoid direct call of template if (empty($conf) || ! is_object($conf)) @@ -28,37 +27,65 @@ if (empty($conf) || ! is_object($conf)) load('ticket'); $linkedObjectBlock = $GLOBALS['linkedObjectBlock']; -echo '
'; -print load_fiche_titre($langs->trans('RelatedTickets')); + +// Load translation files required by the page +$langs->load('ticket'); + +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'datec', 'desc', 0, 0, 1); + +$total=0; $ilink=0; +foreach($linkedObjectBlock as $key => $objectlink) +{ + $ilink++; + + $trclass='oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total'; ?> -
'; @@ -562,10 +563,11 @@ print '
- - - - - + + + + + + socid = $objectlink->fk_soc; + //$objectlink->fetch_thirdparty(); + ?> + + + - - - +} +if (count($linkedObjectBlock) > 1) +{ + ?> + + + + + + + + + socid = $object->fk_soc; - $object->fetch_thirdparty(); - ?> - - - - -
trans("Subject"); ?>trans("DateCreation"); ?>trans("Customer"); ?>trans("Status"); ?>
trans("Ticket"); ?> + global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES) print ' + getNomUrl(1); ?>ref_client; ?>datec, 'day'); ?>thirdparty->getNomUrl(1); ?>getLibStatut(3); ?> + element != 'shipping') { + ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + +
- subject) ? ' '.$object->subject : ''); ?> - - datec, 'day'); ?>
trans("Total"); ?>
thirdparty->getNomUrl(1); ?>getLibstatut(2); ?>
+} +?>