diff --git a/SECURITY.md b/SECURITY.md index 427b1cc7ae2..9c28e2874b9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,8 +12,7 @@ This file contains some policies about the security reports on Dolibarr ERP CRM ## Reporting a Vulnerability -To report a vulnerability, please use GitHub security advisory at https://github.com/Dolibarr/dolibarr/security/advisories/new (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody) - +To report a vulnerability, please use GitHub security advisory at [https://github.com/Dolibarr/dolibarr/security/advisories/new](https://github.com/Dolibarr/dolibarr/security/advisories/new) (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody) ## Hunting vulnerabilities on Dolibarr @@ -23,7 +22,7 @@ If you believe you've found a security bug in our service, we are happy to work Any type of denial of service attacks is strictly forbidden, as well as any interference with network equipment and Dolibarr infrastructure. -We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: https://www.dolibarr.org/download) to get access on every side of application. +We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: [https://www.dolibarr.org/download](https://www.dolibarr.org/download)) to get access on every side of application. ### User Agent @@ -31,8 +30,7 @@ If you try to find bug on Dolibarr, we recommend to append to your user-agent he ### Account access -You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from https://www.dolibarr.org/download - +You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from [https://www.dolibarr.org/download](https://www.dolibarr.org/download) ## Eligibility and Responsible Disclosure @@ -46,7 +44,6 @@ You must avoid tests that could cause degradation or interruption of our service You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability. - ## Scope for qualified vulnerabilities ONLY vulnerabilities discovered, when the following setup on test platform is used, are "valid": @@ -64,7 +61,6 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us Scope is the web application (back office) and the APIs. - ## Qualifying vulnerabilities for reporting * Remote code execution (RCE) @@ -81,7 +77,6 @@ Scope is the web application (back office) and the APIs. * Software version disclosure (for non admin users only) * Stack traces or path disclosure (for non admin users only) - ## Non-qualifying vulnerabilities for reporting * "Self" XSS @@ -99,4 +94,3 @@ Scope is the web application (back office) and the APIs. * Software version or private IP disclosure when logged user is admin * Stack traces or path disclosure when logged user is admin * Any vulnerabilities due to a configuration different than the one defined into chapter "Scope for qualified vulnerabilities". - diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 50116b94b23..f3e70ac837a 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -732,17 +732,16 @@ class AccountingAccount extends CommonObject /** * Return Suggest accounting accounts to bind * - * @param Societe $buyer Societe Object Buyers - * @param $seller Company Object seller - * @param Product $product Product object sell or buy - * @param Facture $facture Facture - * @param FactureLigne $factureDet Facture Det - * @param array $accountingAccount array of Account account - * @param string $type Customer / Supplier - * - * @return array Accounting accounts suggested + * @param Societe $buyer Object buyer + * @param Societe $seller Object seller + * @param Product $product Product object sell or buy + * @param Facture $facture Facture + * @param FactureLigne $factureDet Facture Det + * @param array $accountingAccount Array of Account account + * @param string $type Customer / Supplier + * @return array Accounting accounts suggested */ - public function getAccountingCodeToBind(Societe $buyer, $seller, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array(), $type = '') + public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array(), $type = '') { global $conf; global $hookmanager; @@ -755,21 +754,21 @@ class AccountingAccount extends CommonObject $reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { - if ($type=='customer') { + if ($type == 'customer') { $const_name = "SOLD"; - } elseif ($type=='supplier') { + } elseif ($type == 'supplier') { $const_name = "BUY"; } require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; $isBuyerInEEC = isInEEC($buyer); $isSellerInEEC = isInEEC($seller); - $code_l = ''; - $code_p = ''; - $code_t = ''; + $code_l = ''; // Default value for generic product/service + $code_p = ''; // Value for the product/service in parameter ($product) + $code_t = ''; // Default value of product account for the thirdparty $suggestedid = ''; - // Level 1: Search suggested default account for product/service + // Level 1 (define $code_l): Search suggested default account for product/service $suggestedaccountingaccountbydefaultfor = ''; if ($factureDet->product_type == 1) { if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) @@ -814,7 +813,7 @@ class AccountingAccount extends CommonObject $code_l = ''; } - // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) + // Level 2 (define $code_p): Search suggested account for product/service (similar code exists in page index.php to make automatic binding) $suggestedaccountingaccountfor = ''; if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) { // If buyer in same country than seller (if not defined, we assume it is same country) @@ -866,7 +865,7 @@ class AccountingAccount extends CommonObject } } - // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + // Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { if (!empty($buyer->code_compta)) { $code_t = $buyer->code_compta; @@ -888,6 +887,7 @@ class AccountingAccount extends CommonObject $suggestedaccountingaccountfor = 'deposit'; } + // If $suggestedid could not be guessed yet, we set it from the generic default accounting code $code_l if (empty($suggestedid) && empty($code_p) && !empty($code_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { if (empty($this->accountingaccount_codetotid_cache[$code_l])) { $tmpaccount = new self($this->db); diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index c07f4854b84..ab1ac678262 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -478,7 +478,6 @@ if ($result) { print ''; print ''; print ''; - //print ''; print ''; print ''; print ''; @@ -528,6 +527,9 @@ if ($result) { while ($i < min($num_lines, $limit)) { $objp = $db->fetch_object($result); + // product_type: 0 = service, 1 = product + // if product does not exist we use the value of product_type provided in facturedet to define if this is a product or service + // issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB ! $code_sell_l = ''; $code_sell_p = ''; @@ -586,9 +588,9 @@ if ($result) { $suggestedid=$return['suggestedid']; $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor']; $suggestedaccountingaccountbydefaultfor=$return['suggestedaccountingaccountbydefaultfor']; - $code_sell_l=$return['code_sell_l']; - $code_sell_p=$return['code_sell_p']; - $code_sell_t=$return['code_sell_t']; + $code_sell_l=$return['code_l']; + $code_sell_p=$return['code_p']; + $code_sell_t=$return['code_t']; } //var_dump($return); @@ -661,11 +663,11 @@ if ($result) { print ''; // Vat rate - $code_vat_differ=''; - if ($product_static->tva_tx !== $facture_static_det->tva_tx && ! empty($facture_static_det->tva_tx)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export - $code_vat_differ = 'font-weight:bold; text-decoration:blink; color:red'; + $code_vat_differ = ''; + if ($product_static->tva_tx !== $facture_static_det->tva_tx && price2num($product_static->tva_tx) && price2num($facture_static_det->tva_tx)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export + $code_vat_differ = 'warning bold'; } - print ''; + print ''; print vatrate($facture_static_det->tva_tx.($facture_static_det->vat_src_code ? ' ('.$facture_static_det->vat_src_code.')' : '')); print ''; @@ -731,12 +733,13 @@ if ($result) { // Column with checkbox print ''; + $ischecked = 0; if (!empty($suggestedid) && $suggestedaccountingaccountfor <> '') { - $ischecked=1; + $ischecked = 1; } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { $ischecked = 0; } - print ''; + print ''; print ''; print ''; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index b7e914c381a..a189727494c 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -529,11 +529,12 @@ if ($result) { while ($i < min($num_lines, $limit)) { $objp = $db->fetch_object($result); - // product_type: 0 = service ? 1 = product + // product_type: 0 = service, 1 = product // if product does not exist we use the value of product_type provided in facturedet to define if this is a product or service // issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB ! $objp->code_buy_l = ''; $objp->code_buy_p = ''; + $objp->aarowid_suggest = ''; // Will be set later $thirdpartystatic->id = $objp->socid; $thirdpartystatic->name = $objp->name; @@ -575,10 +576,6 @@ if ($result) { $facturefourn_static_det->product_type = $objp->type_l; $facturefourn_static_det->desc = $objp->description; - $code_buy_p_notset = ''; - $code_buy_t_notset = ''; - $objp->aarowid_suggest = ''; // Will be set later - $accountingAccountArray = array( 'dom'=>$objp->aarowid, 'intra'=>$objp->aarowid_intra, @@ -595,12 +592,15 @@ if ($result) { $suggestedid=$return['suggestedid']; $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor']; $suggestedaccountingaccountbydefaultfor=$return['suggestedaccountingaccountbydefaultfor']; - $code_buy_l=$return['code_buy_l']; - $code_buy_p=$return['code_buy_p']; - $code_buy_t=$return['code_buy_t']; + $code_buy_l=$return['code_l']; + $code_buy_p=$return['code_p']; + $code_buy_t=$return['code_t']; } //var_dump($return); + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + // Not supported for suppliers + if (!empty($code_buy_p)) { // Value was defined previously } else { @@ -654,11 +654,11 @@ if ($result) { print ''; // Vat rate - $code_vat_differ=''; - if ($objp->vat_tx_l != $objp->vat_tx_p && ! empty($objp->vat_tx_l)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export - $code_vat_differ = 'font-weight:bold; text-decoration:blink; color:red'; + $code_vat_differ = ''; + if ($objp->vat_tx_l != $objp->vat_tx_p && price2num($objp->vat_tx_p) && price2num($objp->vat_tx_l)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export + $code_vat_differ = 'warning bold'; } - print ''; + print ''; print vatrate($facturefourn_static_det->tva_tx.($facturefourn_static_det->vat_src_code ? ' ('.$facturefourn_static_det->vat_src_code.')' : '')); print ''; @@ -691,6 +691,11 @@ if ($result) { $shelp = ''; $ttype = 'help'; if ($suggestedaccountingaccountfor == 'eec') { $shelp = $langs->trans("SaleEEC"); + } elseif ($suggestedaccountingaccountfor == 'eecwithvat') { + $shelp = $langs->trans("SaleEECWithVAT"); + } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { + $shelp = $langs->trans("SaleEECWithoutVATNumber"); + $ttype = 'warning'; } elseif ($suggestedaccountingaccountfor == 'export') { $shelp = $langs->trans("SaleExport"); } @@ -719,12 +724,13 @@ if ($result) { // Column with checkbox print ''; - if (!empty($suggestedid)) { + $ischecked = 0; + if (!empty($suggestedid) && $suggestedaccountingaccountfor <> '') { $ischecked = 1; - } else { + } elseif ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') { $ischecked = 0; } - print ''; + print ''; print ''; print ''; diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 1a64f2304e1..6f1bab2cda4 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -943,7 +943,7 @@ if ($rowid > 0) { } if (!$datefrom) { $datefrom = $object->datevalid; - if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) < dol_now()) { + if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) > dol_now()) { $datefrom = dol_time_plus_duree($object->datefin, 1, 'd'); } else { $datefrom = dol_get_first_day(dol_print_date(time(), "%Y")); diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index f0211d1b795..da76f01fd6c 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -70,6 +70,9 @@ print ''."\n".''; $arrayofnatures = array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers")); diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index e0fdb740782..ec2ad4a815a 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -98,7 +98,9 @@ if (!empty($ExecTimeLimit)) { @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64 error_reporting($err); } -$MemoryLimit = 0; + +/* If value has been forced with a php_admin_value, this has no effect. Example of value: '512M' */ +$MemoryLimit = getDolGlobalString('MAIN_MEMORY_LIMIT_ARCHIVE_DATAROOT'); if (!empty($MemoryLimit)) { @ini_set('memory_limit', $MemoryLimit); } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 31ad955afdb..748aea4ddb2 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -737,14 +737,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $MAXEVENT = 10; - $morehtmlright = ''; - $morehtmlright .= $langs->trans("SeeAll"); - $morehtmlright .= ''; + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/bom/bom_agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, 0, 1, '', $MAXEVENT, '', $morehtmlcenter); print ''; } diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 8abbdaa0dd3..1959fd29eca 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -57,12 +57,12 @@ $date_start = GETPOST('date_start', 'alpha'); $date_startDay = GETPOST('date_startday', 'int'); $date_startMonth = GETPOST('date_startmonth', 'int'); $date_startYear = GETPOST('date_startyear', 'int'); -$date_start = ($date_startDay ? dol_mktime(0, 0, 0, $date_startMonth, $date_startDay, $date_startYear, 'tzuserrel') : dol_stringtotime($date_start)); +$date_start = dol_mktime(0, 0, 0, $date_startMonth, $date_startDay, $date_startYear, 'tzuserrel'); $date_stop = GETPOST('date_stop', 'alpha'); $date_stopDay = GETPOST('date_stopday', 'int'); $date_stopMonth = GETPOST('date_stopmonth', 'int'); $date_stopYear = GETPOST('date_stopyear', 'int'); -$date_stop = ($date_stopDay ? dol_mktime(23, 59, 59, $date_stopMonth, $date_stopDay, $date_stopYear, 'tzuserrel') : dol_stringtotime($date_stop)); +$date_stop = dol_mktime(23, 59, 59, $date_stopMonth, $date_stopDay, $date_stopYear, 'tzuserrel'); $action = GETPOST('action', 'aZ09'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -348,8 +348,8 @@ if (($action == 'searchfiles' || $action == 'dl')) { $nofile = array(); $nofile['id'] = $objd->id; $nofile['entity'] = $objd->entity; - $nofile['date'] = $db->idate($objd->date); - $nofile['date_due'] = $db->idate($objd->date_due); + $nofile['date'] = $db->jdate($objd->date); + $nofile['date_due'] = $db->jdate($objd->date_due); $nofile['paid'] = $objd->paid; $nofile['amount_ht'] = $objd->total_ht; $nofile['amount_ttc'] = $objd->total_ttc; @@ -368,8 +368,8 @@ if (($action == 'searchfiles' || $action == 'dl')) { foreach ($files as $key => $file) { $file['id'] = $objd->id; $file['entity'] = $objd->entity; - $file['date'] = $db->idate($objd->date); - $file['date_due'] = $db->idate($objd->date_due); + $file['date'] = $db->jdate($objd->date); + $file['date_due'] = $db->jdate($objd->date_due); $file['paid'] = $objd->paid; $file['amount_ht'] = $objd->total_ht; $file['amount_ttc'] = $objd->total_ttc; @@ -460,7 +460,7 @@ if ($result && $action == "dl" && !$error) { $log .= ','.$langs->transnoentitiesnoconv("Country"); $log .= ','.$langs->transnoentitiesnoconv("VATIntra"); $log .= ','.$langs->transnoentitiesnoconv("Sens")."\n"; - $zipname = $dirfortmpfile.'/'.dol_print_date($date_start, 'dayrfc')."-".dol_print_date($date_stop, 'dayrfc').'_export.zip'; + $zipname = $dirfortmpfile.'/'.dol_print_date($date_start, 'dayrfc', 'tzuserrel')."-".dol_print_date($date_stop, 'dayrfc', 'tzuserrel').'_export.zip'; dol_delete_file($zipname); @@ -608,10 +608,14 @@ if (!empty($date_start) && !empty($date_stop)) { print '
'."\n"; print ''; - echo dol_print_date($date_start, 'day')." - ".dol_print_date($date_stop, 'day'); + echo dol_print_date($date_start, 'day', 'tzuserrel')." - ".dol_print_date($date_stop, 'day', 'tzuserrel'); - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; foreach ($listofchoices as $choice => $val) { print ''; } @@ -741,19 +745,19 @@ if (!empty($date_start) && !empty($date_stop)) { print ''.$data['paid'].''; // Total ET - print ''.price($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."\n"; // Total IT - print ''.price($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'], 'MT'))."\n"; // Total VAT - print ''.price($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'])."\n"; + print ''.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."\n"; - print ''.$data['thirdparty_name']."\n"; + print ''.dol_escape_htmltag($data['thirdparty_name'])."\n"; print ''.$data['thirdparty_code']."\n"; print ''.$data['country_code']."\n"; - print ''.$data['vatnum']."\n"; + print ''.dol_escape_htmltag($data['vatnum'])."\n"; if ($data['sens']) { $totalET_credit += $data['amount_ht']; diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 8628e287bd0..00a61a7ce7e 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -178,7 +178,6 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); - /* * Actions */ @@ -270,13 +269,15 @@ if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', ' if (!$error) { $param = 'action=reconcile&contextpage=banktransactionlist&id='.$id.'&search_account='.$id; - $param .= '&search_conciliated='.urlencode($search_conciliated); if ($page) { $param .= '&page='.urlencode($page); } if ($offset) { $param .= '&offset='.urlencode($offset); } + if ($search_conciliated != '' && $search_conciliated != '-1') { + $param .= '&search_conciliated='.urlencode($search_conciliated); + } if ($search_thirdparty_user) { $param .= '&search_thirdparty='.urlencode($search_thirdparty_user); } @@ -419,7 +420,6 @@ $banklinestatic = new AccountLine($db); $now = dol_now(); - // Must be before button action $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { @@ -757,7 +757,7 @@ if ($resql) { // Confirmation delete if ($action == 'delete') { $text = $langs->trans('ConfirmDeleteTransaction'); - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid"), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); + print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&rowid='.GETPOST("rowid", 'int'), $langs->trans('DeleteTransaction'), $text, 'confirm_delete', null, '', 1); } // Lines of title fields @@ -1200,7 +1200,7 @@ if ($resql) { $objforbalance = $db->fetch_object($resqlforbalance); if ($objforbalance) { // If sort is desc,desc,desc then total of previous date + amount is the balancebefore of the previous line before the line to show - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balancebefore = $objforbalance->previoustotal + ($sign * $objp->amount); } else { // If sort is asc,asc,asc then total of previous date is balance of line before the next line to show @@ -1285,8 +1285,7 @@ if ($resql) { } } - - if ($sortfield == 'b.datev,b.dateo,b.rowid' && $sortorder == 'desc,desc,desc') { + if ($sortfield == 'b.datev,b.dateo,b.rowid' && ($sortorder == 'desc' || $sortorder == 'desc,desc' || $sortorder == 'desc,desc,desc')) { $balance = price2num($balancebefore, 'MT'); // balance = balancebefore of previous line (sort is desc) $balancebefore = price2num($balancebefore - ($sign * $objp->amount), 'MT'); } else { diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index af0b388cb7a..ae676209571 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -46,7 +46,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("banks", "categories", "companies", "bills", "trips", "donations", "loan")); +$langs->loadLangs(array("banks", "categories", "companies", "bills", "trips", "donations", "loan", "salaries")); $action = GETPOST('action', 'aZ09'); $id = GETPOST('account', 'int') ? GETPOST('account', 'int') : GETPOST('id', 'int'); @@ -481,7 +481,7 @@ if (empty($numref)) { // Description print ''; - print ''; + print ''; $reg = array(); preg_match('/\((.+)\)/i', $objp->label, $reg); // Si texte entoure de parenthese on tente recherche de traduction if ($reg[1] && $langs->trans($reg[1]) != $reg[1]) { @@ -492,7 +492,7 @@ if (empty($numref)) { print ''; /* - * Ajout les liens (societe, company...) + * Add links under the label (link to payment, company, user, social contribution...) */ $newline = 1; $links = $object->get_url($objp->rowid); diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 9665a8a2b1f..f728dc74f4e 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -61,8 +61,8 @@ if ($action == 'add') { $dateo = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $label = GETPOST('label', 'alpha'); - $amount = price2num(GETPOST('amount', 'alpha'), 'MT'); - $amountto = price2num(GETPOST('amountto', 'alpha'), 'MT'); + $amount = price2num(GETPOST('amount', 'alpha'), 'MT', 2); + $amountto = price2num(GETPOST('amountto', 'alpha'), 'MT', 2); if (!$label) { $error++; diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index c7b74abfc39..1950cdb5392 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -128,7 +128,7 @@ if (GETPOST('cancel', 'alpha')) { if ($action == "reopen") { $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'CASHFENCE_REOPEN'); if ($result < 0) { - dol_print_error($db, $object->error, $object->error); + setEventMessages($object->error, $object->error, 'errors'); } $action = 'view'; @@ -312,7 +312,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } elseif ($syear && $smonth && $sday) { $sql .= " AND dateo < '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."'"; } else { - dol_print_error('', 'Year not defined'); + setEventMessages($langs->trans('YearNotDefined'), null, 'errors'); } $resql = $db->query($sql); @@ -356,7 +356,7 @@ if ($action == "create" || $action == "start" || $action == 'close') { } elseif ($syear && $smonth && $sday) { $sql .= " AND datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $smonth, $sday, $syear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $smonth, $sday, $syear))."'"; } else { - dol_print_error('', 'Year not defined'); + setEventMessages($langs->trans('YearNotDefined'), null, 'errors'); } $resql = $db->query($sql); diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 8ccff0eb017..80ba0b671eb 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1295,7 +1295,14 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == ' if ($objectclass == 'Facture' && empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED) && $objecttmp->status != Facture::STATUS_DRAFT) { $langs->load("errors"); $nbignored++; - $resaction .= '
'.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction', $objecttmp->ref).'

'; + $TMsg[] = '
'.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction', $objecttmp->ref).'

'; + continue; + } + + if (method_exists($objecttmp, 'is_erasable') && $objecttmp->is_erasable() <= 0) { + $langs->load("errors"); + $nbignored++; + $TMsg[] = '
'.$langs->trans('ErrorRecordHasChildren').' '.$objecttmp->ref.'

'; continue; } diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index a92179e7b6a..5d0242657ef 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -492,7 +492,7 @@ abstract class CommonDocGenerator $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $already_payed_all, 'MT') ); - if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { + if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { $resarray[$array_key.'_total_discount_ht_locale'] = price($object->getTotalDiscount(), 0, $outputlangs); $resarray[$array_key.'_total_discount_ht'] = price2num($object->getTotalDiscount()); } else { @@ -516,8 +516,9 @@ abstract class CommonDocGenerator // Add vat by rates if (is_array($object->lines) && count($object->lines) > 0) { $totalUp = 0; + // Set substitution keys for different VAT rates foreach ($object->lines as $line) { - // $line->tva_tx format depends on database field accuraty, no reliable. This is kept for backward compatibility + // $line->tva_tx format depends on database field accuracy, no reliable. This is kept for backward compatibility if (empty($resarray[$array_key.'_total_vat_'.$line->tva_tx])) { $resarray[$array_key.'_total_vat_'.$line->tva_tx] = 0; } @@ -538,7 +539,7 @@ abstract class CommonDocGenerator // Note that this added fields does not match a field into database in Dolibarr (Dolibarr manage discount on lines not as a global property of object) $resarray['object_total_up'] = $totalUp; $resarray['object_total_up_locale'] = price($resarray['object_total_up'], 0, $outputlangs); - if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { + if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Propal', 'Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { $totalDiscount = $object->getTotalDiscount(); } else { $totalDiscount = 0; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 56f7c41994b..92dba4d4de0 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1926,7 +1926,7 @@ class Form $sql .= " WHERE u.entity IS NOT NULL"; } } else { - if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug"; $sql .= " ON ug.fk_user = u.rowid"; $sql .= " WHERE ug.entity = ".$conf->entity; @@ -4905,8 +4905,9 @@ class Form $formconfirm .= ($question ? '
'.img_help('', '').' '.$question.'
' : ''); $formconfirm .= ''."\n"; - $formconfirm .= "\n\n"; + $formconfirm .= "\n\n"; $formconfirm .= '