diff --git a/ChangeLog b/ChangeLog index 2bfa9992858..fac6c0a3c06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,43 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 7.0.3 compared to 7.0.2 ***** +FIX: 7.0 task contact card without withproject parameters +FIX: #8722 +FIX: #8762 +FIX: #8813 +FIX: #8858 #8860 Backport better compatibility fix +FIX: #8893 to get formatted price as substitution vars +FIX: Avoid converting into reduction twice and draft invoice +FIX: bad result on fetch ProductStockEntrepot +FIX: Bad substitution key used for default send proposal email +FIX: button to pay still visible when amount null used +FIX: clause must not be there +FIX: Contact tab not visible when using canvas +FIX: dol_delete_file must work in a context without db handler loaded +FIX: entity test must be on product_fourn_price table and not product table +FIX: Fetch shipping will now fetch project id +FIX: If we enable 3 steps for supplier order approbation, we must not delete all fourn rights def. +FIX: intervention: extrafield error when calling insertExtrafields +FIX: It's not possible to remove a contact which is assigned to an event #8852 +FIX: javascript showempty error +FIX: Keep supplier proposal price for supplier order +FIX: link for projets not linked to a thirdparties +FIX: Missing extrafields in export of stock or products +FIX: missing filters during ordering +FIX: missing filters during reordering +FIX: missing parenthesis +FIX: need to filter on aa.entity for same accounting accounts available in several entities +FIX: picto for type in product link in accountany list is wrong +FIX: Problems in accountancy module when using multicompany module. +FIX: proposal: missing contact type translation key +FIX: pu_ht_devise was not converted to numeric so decimals were lost when calculating total_ht_devise +FIX: Select user on add time spent form +FIX: shipment: fk_proje(c)t not handled in fetch() and update() methods +FIX: sometimes amounts are identical but php find them different. +FIX: supplier order: product supplier ref not saved on addline +FIX: test is_erasable() must be done before call function delete() too to avoid delete invoice with &action=delete in url +FIX: wrong var name $search_month_lim ***** ChangeLog for 8.0.0 compared to 7.0.0 ***** diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index 4a5e77a434b..ff3a38769b8 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -21,6 +21,7 @@ * \ingroup Advanced accountancy * \brief Setup page to configure journals */ + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index ec8f1f67bdf..6719e7091c8 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -44,7 +44,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; // Load translation files required by the page -$langs->loadLangs(array('bills', 'compta', 'admin', 'other')); +$langs->loadLangs(array('bills', 'compta', 'admin', 'other', 'products')); $action = GETPOST('action','alpha'); $massaction = GETPOST('massaction','alpha'); diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 8b71cf40064..539c70f591b 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2014 Raphaël Doursenaud * Copyright (C) 2014 Marcos García * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2018 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -292,39 +293,40 @@ class Paiement extends CommonObject { $amount_ht = $amount_tva = $amount_ttc = array(); - // Loop on each vat rate - $i = 0; - foreach ($invoice->lines as $line) - { - if ($line->total_ht!=0) - { // no need to create discount if amount is null - $amount_ht[$line->tva_tx] += $line->total_ht; - $amount_tva[$line->tva_tx] += $line->total_tva; - $amount_ttc[$line->tva_tx] += $line->total_ttc; - $i ++; - } - } + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($this->db); + $discount->fetch('',$invoice->id); + if (empty($discount->id)) { // If the invoice was not yet converted into a discount (this may have been done manually before we come here) - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($this->db); - $discount->description = '(DEPOSIT)'; - $discount->fk_soc = $invoice->socid; - $discount->fk_facture_source = $invoice->id; - foreach ($amount_ht as $tva_tx => $xxx) - { - $discount->amount_ht = abs($amount_ht[$tva_tx]); - $discount->amount_tva = abs($amount_tva[$tva_tx]); - $discount->amount_ttc = abs($amount_ttc[$tva_tx]); - $discount->tva_tx = abs($tva_tx); + $discount->description = '(DEPOSIT)'; + $discount->fk_soc = $invoice->socid; + $discount->fk_facture_source = $invoice->id; - $result = $discount->create($user); - if ($result < 0) - { - $error++; - break; - } - } + // Loop on each vat rate + $i = 0; + foreach ($invoice->lines as $line) { + if ($line->total_ht != 0) { // no need to create discount if amount is null + $amount_ht[$line->tva_tx] += $line->total_ht; + $amount_tva[$line->tva_tx] += $line->total_tva; + $amount_ttc[$line->tva_tx] += $line->total_ttc; + $i++; + } + } + + foreach ($amount_ht as $tva_tx => $xxx) { + $discount->amount_ht = abs($amount_ht[$tva_tx]); + $discount->amount_tva = abs($amount_tva[$tva_tx]); + $discount->amount_ttc = abs($amount_ttc[$tva_tx]); + $discount->tva_tx = abs($tva_tx); + + $result = $discount->create($user); + if ($result < 0) { + $error++; + break; + } + } + } if ($error) { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 231b1461cc8..9a9d3279e03 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1052,7 +1052,7 @@ class Form * * @param string $selected Preselected type * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)') + * @param string $filter Optional filters criteras (example: 's.rowid <> x', 's.client in (1,3)') * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') * @param int $showtype Show third party type in combolist (customer, prospect or supplier) * @param int $forcecombo Force to use standard HTML select component without beautification @@ -1072,6 +1072,9 @@ class Form $num=0; $outarray=array(); + // Clean $filter that may contains sql conditions so sql code + if (function_exists('test_sql_and_script_inject')) $filter = test_sql_and_script_inject($filter, 3); + // On recherche les societes $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur"; $sql.= " FROM ".MAIN_DB_PREFIX ."societe as s"; @@ -1437,12 +1440,12 @@ class Form * @param int $disabled If select list must be disabled * @param array $include Array list of users id to include * @param int $enableonly Array list of users id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force + * @param string $force_entity '0' or Ids of environment to force * @return void * @deprecated Use select_dolusers instead * @see select_dolusers() */ - function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity=0) + function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity='0') { print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity); } @@ -1457,7 +1460,7 @@ class Form * @param int $disabled If select list must be disabled * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me * @param array $enableonly Array list of users id to be enabled. If defined, it means that others will be disabled - * @param int $force_entity 0 or Id of environment to force + * @param string $force_entity '0' or Ids of environment to force * @param int $maxlength Maximum length of string into list (0=no limit) * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request (Example: 'employee = 1') @@ -1469,7 +1472,7 @@ class Form * @return string HTML select string * @see select_dolgroups */ - function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0, $outputmode=0) + function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity='0', $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0, $outputmode=0) { global $conf,$user,$langs; @@ -1606,13 +1609,13 @@ class Form } if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) { - if ($obj->admin && ! $obj->entity) + if (! $obj->entity) { $out.=($moreinfo?' - ':' (').$langs->trans("AllEntities"); $moreinfo++; } else - { + { $out.=($moreinfo?' - ':' (').($obj->label?$obj->label:$langs->trans("EntityNameNotDefined")); $moreinfo++; } @@ -1656,7 +1659,7 @@ class Form * @param int $disabled If select list must be disabled * @param array $include Array list of users id to include or 'hierarchy' to have only supervised users * @param array $enableonly Array list of users id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force + * @param int $force_entity '0' or Ids of environment to force * @param int $maxlength Maximum length of string into list (0=no limit) * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request @@ -1667,7 +1670,7 @@ class Form * @return string HTML select string * @see select_dolgroups */ - function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $showproperties=0, $listofuserid=array(), $listofcontactid=array(), $listofotherid=array()) + function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity='0', $maxlength=0, $showstatus=0, $morefilter='', $showproperties=0, $listofuserid=array(), $listofcontactid=array(), $listofotherid=array()) { global $conf, $user, $langs; @@ -6723,11 +6726,11 @@ class Form * @param int $disabled If select list must be disabled * @param string $include Array list of groups id to include * @param int $enableonly Array list of groups id to be enabled. All other must be disabled - * @param int $force_entity 0 or Id of environment to force + * @param string $force_entity '0' or Ids of environment to force * @return string * @see select_dolusers */ - function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0) + function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity='0') { global $conf,$user,$langs; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 65191a0129e..450c294f19e 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -420,7 +420,7 @@ function societe_admin_prepare_head() * @param Translate $outputlangs Langs object for output translation * @param int $entconv 0=Return value without entities and not converted to output charset, 1=Ready for html output * @param int $searchlabel Label of country to search (warning: searching on label is not reliable) - * @return mixed String with country code or translated country name or Array('id','code','label') + * @return mixed Integer with country id or String with country code or translated country name or Array('id','code','label') or 'NotDefined' */ function getCountry($searchkey, $withcode='', $dbtouse=0, $outputlangs='', $entconv=1, $searchlabel='') { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a4a874e792b..54bbbc837a1 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5773,6 +5773,7 @@ function dol_textishtml($msg,$option=0) if (preg_match('//i',$msg)) return true; + elseif (preg_match('//i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|p|span|strong|table)\s+[^<>\/]*\/>/i',$msg)) return true; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index f2594f85f82..141260d36f3 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1355,7 +1355,7 @@ if ($action == 'create') if (GETPOST('fk_user_author', 'int') > 0) $defaultselectuser=GETPOST('fk_user_author', 'int'); $include_users = 'hierarchyme'; if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); - $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); + $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity); print $s; print ''; print ''; diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index e01ab071e1f..b7c81c4d33a 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -2425,7 +2425,7 @@ class ExpenseReportLine $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; // Sometimes type of expense report has been removed, so we use a left join here. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.rowid = '.$rowid; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 3ba0089070c..dece376cc5a 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 5037e3a8656..494c572eaad 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -868,12 +868,13 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create print ''; print ''.$langs->trans("User").''; print ''; + if (empty($user->rights->holiday->write_all)) { - print $form->select_dolusers(($fuserid?$fuserid:$user->id), 'fuserid', 0, '', 0, 'hierarchyme', '', 0, 0, 0, $morefilter, 0, '', 'maxwidth300'); + print $form->select_dolusers(($fuserid?$fuserid:$user->id), 'fuserid', 0, '', 0, 'hierarchyme', '', '0,'.$conf->entity, 0, 0, $morefilter, 0, '', 'maxwidth300'); //print ''; } - else print $form->select_dolusers(GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id, 'fuserid', 0, '', 0, '', '', 0, 0, 0, $morefilter, 0, '', 'maxwidth300'); + else print $form->select_dolusers(GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id, 'fuserid', 0, '', 0, '', '', '0,'.$conf->entity, 0, 0, $morefilter, 0, '', 'maxwidth300'); print ''; print ''; diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index 6bb8508a70b..5327269fbe5 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -36,6 +36,11 @@ ALTER TABLE llx_accounting_account DROP FOREIGN KEY fk_accountingaccount_fk_pcg_ -- Drop foreign key, so next alter will be a success -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account DROP FOREIGN KEY fk_accounting_account_fk_pcg_version; +-- VMYSQL4.1 SET sql_mode = 'ALLOW_INVALID_DATES'; +-- VMYSQL4.1 update llx_accounting_account set tms = datec where DATE(STR_TO_DATE(tms, '%Y-%m-%d')) IS NULL; +-- VMYSQL4.1 SET sql_mode = 'NO_ZERO_DATE'; +-- VMYSQL4.1 update llx_accounting_account set tms = datec where DATE(STR_TO_DATE(tms, '%Y-%m-%d')) IS NULL; + -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY fk_pcg_version VARCHAR(20) CHARACTER SET utf8; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY fk_pcg_version VARCHAR(20) COLLATE utf8_unicode_ci; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_system MODIFY pcg_version VARCHAR(20) CHARACTER SET utf8; diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 9493ef6c7c9..22409441eac 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -391,6 +391,11 @@ drop table tmp_bank_url_expense_user; -- where price = 17.5 +-- VMYSQL4.1 SET sql_mode = 'ALLOW_INVALID_DATES'; +-- VMYSQL4.1 update llx_accounting_account set tms = datec where DATE(STR_TO_DATE(tms, '%Y-%m-%d')) IS NULL; +-- VMYSQL4.1 SET sql_mode = 'NO_ZERO_DATE'; +-- VMYSQL4.1 update llx_accounting_account set tms = datec where DATE(STR_TO_DATE(tms, '%Y-%m-%d')) IS NULL; + -- VMYSQL4.1 SET sql_mode = 'ALLOW_INVALID_DATES'; -- VMYSQL4.1 update llx_expensereport set date_debut = date_create where DATE(STR_TO_DATE(date_debut, '%Y-%m-%d')) IS NULL; -- VMYSQL4.1 SET sql_mode = 'NO_ZERO_DATE'; diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 7745dde08da..5a7169ac925 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -75,6 +75,7 @@ AvailabilityTypeAV_1M=1 month TypeContact_propal_internal_SALESREPFOLL=Representative following-up proposal TypeContact_propal_external_BILLING=Customer invoice contact TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal +TypeContact_propal_external_SHIPPING=Customer contact for delivery # Document models DocModelAzurDescription=A complete proposal model (logo...) DefaultModelPropalCreate=Default model creation diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index 01d768261f9..f6543c89a80 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -82,7 +82,7 @@ PredefinedMailTest=__(Hello)__,\nCeci est un mail de test envoyé à __EMAIL__.\ PredefinedMailTestHtml=__(Hello)__\nCeci est un message de test (le mot test doit être en gras).
Les 2 lignes sont séparées par un retour à la ligne.

__SIGNATURE__ PredefinedMailContentSendInvoice=__(Hello)__\n\nVous trouverez ci-joint la facture __REF__\n\nVoici le lien pour effectuer votre paiement en ligne si elle n'est pas déjà été payée:\n__ONLINE_PAYMENT_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nNous souhaitons vous prévenir que la facture __REF__ ne semble pas avoir été payée. Voici donc la facture en pièce jointe, à titre de rappel.\n\nVoici le lien pour effectuer votre paiement en ligne:\n__ONLINE_PAYMENT_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendProposal=__(Hello)__\n\nYou will find here the commercial proposal __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ +PredefinedMailContentSendProposal=__(Hello)__\n\nVeuillez trouver, ci-joint, la proposition commerciale __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nVeuillez trouver, ci-joint, une demande de prix avec la référence __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ PredefinedMailContentSendOrder=__(Hello)__\n\nVeuillez trouver, ci-joint, la commande __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nVeuillez trouver, ci-joint, notre commande __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 3b4c0178516..0d724e1ce5c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -72,24 +72,30 @@ if (function_exists('get_magic_quotes_gpc')) // magic_quotes_* deprecated in PHP * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF). * * @param string $val Value - * @param string $type 1=GET, 0=POST, 2=PHP_SELF + * @param string $type 1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test) * @return int >0 if there is an injection, 0 if none */ function test_sql_and_script_inject($val, $type) { $inj = 0; // For SQL Injection (only GET are used to be included into bad escaped SQL requests) - if ($type == 1) + if ($type == 1 || $type == 3) { - $inj += preg_match('/updatexml\(/i', $val); $inj += preg_match('/delete\s+from/i', $val); $inj += preg_match('/create\s+table/i', $val); $inj += preg_match('/insert\s+into/i', $val); $inj += preg_match('/select\s+from/i', $val); $inj += preg_match('/into\s+(outfile|dumpfile)/i', $val); + $inj += preg_match('/user\s*\(/i', $val); // avoid to use function user() that return current database login + $inj += preg_match('/information_schema/i', $val); // avoid to use request that read information_schema database } - if ($type != 2) // Not common, we can check on POST + if ($type == 3) { + $inj += preg_match('/select|update|delete|replace|group\s+by|concat|count|from/i', $val); + } + if ($type != 2) // Not common key strings, so we can check them both on GET and POST + { + $inj += preg_match('/updatexml\(/i', $val); $inj += preg_match('/update.+set.+=/i', $val); $inj += preg_match('/union.+select/i', $val); $inj += preg_match('/(\.\.%2f)+/i', $val); @@ -1620,8 +1626,6 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a print ''; - //unset($form); - print '
'; print "\n\n"; } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index c27b69f95b0..39a5697ad72 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -289,8 +289,8 @@ if (empty($reshook)) $object->url = GETPOST('url'); $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; // deprecated - $object->customcode = GETPOST('customcode'); - $object->country_id = GETPOST('country_id'); + $object->customcode = GETPOST('customcode','alpha'); + $object->country_id = GETPOST('country_id','int'); $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->fk_default_warehouse = GETPOST('fk_default_warehouse'); @@ -307,13 +307,13 @@ if (empty($reshook)) $object->surface_units = GETPOST('surface_units'); $object->volume = GETPOST('volume'); $object->volume_units = GETPOST('volume_units'); - $object->finished = GETPOST('finished'); - $object->fk_unit = GETPOST('units'); + $object->finished = GETPOST('finished','alpha'); + $object->fk_unit = GETPOST('units','alpha'); - $accountancy_code_sell = GETPOST('accountancy_code_sell'); - $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra'); - $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export'); - $accountancy_code_buy = GETPOST('accountancy_code_buy'); + $accountancy_code_sell = GETPOST('accountancy_code_sell','alpha'); + $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra','alpha'); + $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export','alpha'); + $accountancy_code_buy = GETPOST('accountancy_code_buy','alpha'); if ($accountancy_code_sell <= 0) { $object->accountancy_code_sell = ''; } else { $object->accountancy_code_sell = $accountancy_code_sell; } if ($accountancy_code_sell_intra <= 0) { $object->accountancy_code_sell_intra = ''; } else { $object->accountancy_code_sell_intra = $accountancy_code_sell_intra; } @@ -386,11 +386,11 @@ if (empty($reshook)) $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; } - $object->customcode = GETPOST('customcode'); - $object->country_id = GETPOST('country_id'); - $object->status = GETPOST('statut'); - $object->status_buy = GETPOST('statut_buy'); - $object->status_batch = GETPOST('status_batch'); + $object->customcode = GETPOST('customcode','alpha'); + $object->country_id = GETPOST('country_id','int'); + $object->status = GETPOST('statut','int'); + $object->status_buy = GETPOST('statut_buy','int'); + $object->status_batch = GETPOST('status_batch','aZ09'); // removed from update view so GETPOST always empty $object->fk_default_warehouse = GETPOST('fk_default_warehouse'); /* @@ -412,7 +412,7 @@ if (empty($reshook)) $object->surface_units = GETPOST('surface_units'); $object->volume = GETPOST('volume'); $object->volume_units = GETPOST('volume_units'); - $object->finished = GETPOST('finished'); + $object->finished = GETPOST('finished','alpha'); $units = GETPOST('units', 'int'); @@ -439,10 +439,10 @@ if (empty($reshook)) $object->barcode_type_coder = $stdobject->barcode_type_coder; $object->barcode_type_label = $stdobject->barcode_type_label; - $accountancy_code_sell = GETPOST('accountancy_code_sell'); - $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra'); - $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export'); - $accountancy_code_buy = GETPOST('accountancy_code_buy'); + $accountancy_code_sell = GETPOST('accountancy_code_sell','alpha'); + $accountancy_code_sell_intra = GETPOST('accountancy_code_sell_intra','alpha'); + $accountancy_code_sell_export = GETPOST('accountancy_code_sell_export','alpha'); + $accountancy_code_buy = GETPOST('accountancy_code_buy','alpha'); if ($accountancy_code_sell <= 0) { $object->accountancy_code_sell = ''; } else { $object->accountancy_code_sell = $accountancy_code_sell; } if ($accountancy_code_sell_intra <= 0) { $object->accountancy_code_sell_intra = ''; } else { $object->accountancy_code_sell_intra = $accountancy_code_sell_intra; } diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index d867848345d..7c18dc11281 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -82,6 +82,9 @@ if ($id > 0 || ! empty($ref)) $result = $object->fetch($id, $ref); } + +if(empty($id) && !empty($object->id)) $id = $object->id; + $modulepart='product'; // Get object canvas (By default, this is not defined, so standard usage of dolibarr) @@ -127,7 +130,7 @@ if ($action == 'addlimitstockwarehouse' && !empty($user->rights->produit->creer) if($maj_ok) { $pse = new ProductStockEntrepot($db); - if($pse->fetch('', GETPOST('id'), GETPOST('fk_entrepot')) > 0) { + if($pse->fetch('', $id, GETPOST('fk_entrepot')) > 0) { // Update $pse->seuil_stock_alerte = $seuil_stock_alerte; @@ -138,7 +141,7 @@ if ($action == 'addlimitstockwarehouse' && !empty($user->rights->produit->creer) // Create $pse->fk_entrepot = GETPOST('fk_entrepot'); - $pse->fk_product = GETPOST('id'); + $pse->fk_product = $id; $pse->seuil_stock_alerte = GETPOST('seuil_stock_alerte'); $pse->desiredstock = GETPOST('desiredstock'); if($pse->create($user) > 0) setEventMessage($langs->trans('ProductStockWarehouseCreated')); @@ -147,7 +150,7 @@ if ($action == 'addlimitstockwarehouse' && !empty($user->rights->produit->creer) } - header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id')); + header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); exit; } @@ -948,7 +951,7 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) if (!empty($user->rights->produit->creer)){ print '
'; print ''; - print ''; + print ''; } print ''; if (!empty($user->rights->produit->creer)){ @@ -965,7 +968,7 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) } $pse = new ProductStockEntrepot($db); - $lines = $pse->fetchAll(GETPOST('id')); + $lines = $pse->fetchAll($id); if (!empty($lines)) { @@ -978,7 +981,7 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) print ''; print ''; if (!empty($user->rights->produit->creer)){ - print ''; + print ''; } print ''; } diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index 349e19b0c26..d62c8a445d6 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -87,7 +87,7 @@ else if (! $searchkey) return; - $form = new Form($db); + if (! is_object($form)) $form = new Form($db); $arrayresult=$form->select_thirdparty_list(0, $htmlname, $filter, 1, $showtype, 0, null, $searchkey, $outjson); $db->close();
'.$line['seuil_stock_alerte'].''.$line['desiredstock'].''.img_delete().''.img_delete().'