diff --git a/ChangeLog b/ChangeLog index 5b73c4b2212..67021ea4d09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -325,6 +325,63 @@ Following changes may create regressions for some external modules, but were nec * Dolibarr v13 is still compatible with any PHP version between 5.6.0 and 7.4.*; Unit tests are OK with PHP 8.0 but some warnings or troubles may appears with PHP 8.0. * All your Ajax services must contains such a line at begin of file: if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal + + +***** ChangeLog for 12.0.5 compared to 12.0.4 ***** +FIX: before crediting a withdrawal receipt, check whether it has been credited already +FIX: mandatory extrafields of type sellist +FIX: when a mandatory extrafield of type sellist contains '0' it should be considered empty and trigger an error message upon insertion +FIX: when a new intervention is created from an object, a new $extrafields object is instantiated but not initialized +FIX: "openall" filter on ticket list does not include read tickets +FIX: ticket - extrafields of type 'date' are not saved +FIX: ticket - the "openall" filter on the ticket list does not include tickets with status READ +FIX: #14290 #15900 +FIX: #15388 #15891 +FIX: #15465 External user sees last 5 shipments to other customers in the dashboard +FIX: #15629 +FIX: #15751 Miscellaneous payment type change to 0 after updating subledger account +FIX: #15946 +FIX: #15966 #15967 +FIX: Accountancy - Fix some problems on CEGID export +FIX: Accountancy - label_operation is used instead of label_compte +FIX: Accountancy - Retire entire opening balance feature +FIX: add autofix of count of email target when data is corrupted +FIX: add categories params on llxHeader filter +FIX: Add critical price patch from 12 to 11. +FIX: Bad cleaning of VAT rate when numbers are into code +FIX: Bad dates filtering in the ticket list causes sql error +FIX: balance starting and ending fiscal month #14197 +FIX: bom line unit display #13831 +FIX: cash fence for takepos with multientity +FIX: Check of customer/vendor code fails in some cases +FIX: create ticket : thirdparty/contact notification #15629 +FIX: Creation of thirdparty when setup is empty +FIX: Dates of sales start in TakePOS +FIX: dupliacete customer or supplier code must be error dipslayed with new code proposed +FIX: Export FEC - Force Carriage Return Line Feed +FIX: Facture Situation Out : status condition +FIX: Filter on date of next generation on template invoices +FIX: Fix detect dispatched product and set to received completely when the supplier order have services (support STOCK_SUPPORTS_SERVICES) +FIX: Invoice Situation Out : status condition +FIX: issue 15659 : Missing test if supplier conf is enabled +FIX: link to create event when task is in a project with a thirdparty +FIX: Localtax must be converted with price2num +FIX: manage price min for PRODUIT_CUSTOMER_PRICES +FIX: missing GETPOST parameters on card_presend.tpl.php +FIX: missing socid into link to create event from project agenda tab +FIX: Must delete extrafields before main table on product deletion. +FIX: (path) htdocs removed +FIX: php alert sms.php +FIX: right to show VAT rate in product list +FIX: select default mail template +FIX: Timeout during import +FIX: update order by api +FIX: useless tracking number displayed on pdf if empty issue #14501 +FIX: Visible date of payment +FIX: warning when adding a line if $remise_percent is an empty string +FIX: When creating a new POS sell, the creation date must be modified. +FIX: wrong name for search status param issue #15516 + ***** ChangeLog for 12.0.4 compared to 12.0.3 ***** FIX: make formConfirm an addreplace-type hook FIX: regex to remove 'action' parameter: taking feedback from PR#15213 into account diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php index 0790f149da4..3990c968806 100644 --- a/htdocs/compta/bank/various_payment/list.php +++ b/htdocs/compta/bank/various_payment/list.php @@ -251,7 +251,7 @@ if ($result) if ($typeid > 0) $param .= '&typeid='.urlencode($typeid); if ($search_amount_deb) $param .= '&search_amount_deb='.urlencode($search_amount_deb); if ($search_amount_cred) $param .= '&search_amount_cred='.urlencode($search_amount_cred); - if ($search_bank_account > 0) $param .= '&search_amount='.urlencode($search_bank_account); + if ($search_bank_account > 0) $param .= '&search_account='.urlencode($search_bank_account); if ($search_accountancy_account > 0) $param .= '&search_accountancy_account='.urlencode($search_accountancy_account); if ($search_accountancy_subledger > 0) $param .= '&search_accountancy_subledger='.urlencode($search_accountancy_subledger); diff --git a/htdocs/compta/cashcontrol/report.php b/htdocs/compta/cashcontrol/report.php index 3dcbfc6519f..32a7e9bede5 100644 --- a/htdocs/compta/cashcontrol/report.php +++ b/htdocs/compta/cashcontrol/report.php @@ -111,7 +111,7 @@ $sql .= " WHERE pf.fk_facture = f.rowid AND p.rowid = pf.fk_paiement AND cp.id = $sql .= " AND f.module_source = '".$db->escape($posmodule)."'"; $sql .= " AND f.pos_source = '".$db->escape($terminalid)."'"; $sql .= " AND f.paye = 1"; -$sql .= " AND p.entity IN (".getEntity('facture').")"; +$sql .= " AND p.entity = ".$conf->entity; // Never share entities for features related to accountancy /*if ($key == 'cash') $sql.=" AND cp.code = 'LIQ'"; elseif ($key == 'cheque') $sql.=" AND cp.code = 'CHQ'"; elseif ($key == 'card') $sql.=" AND cp.code = 'CB'"; diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index b7f8d3c9a3d..8926c2762b2 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -43,12 +43,20 @@ $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); +$object = new Paiement($db); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$result = restrictedArea($user, $object->element, $object->id, 'paiement', ''); + // Security check if ($user->socid) $socid = $user->socid; -// TODO ajouter regle pour restreindre acces paiement -//$result = restrictedArea($user, 'facture', $id,''); - -$object = new Paiement($db); +// Now check also permission on thirdparty of invoices of payments. Thirdparty were loaded by the fetch_object before based on first invoice. +// It should be enough because all payments are done on invoices of the same thirdparty. +if ($socid && $socid != $object->thirdparty->id) { + accessforbidden(); +} /* @@ -59,7 +67,6 @@ if ($action == 'setnote' && $user->rights->facture->paiement) { $db->begin(); - $object->fetch($id); $result = $object->update_note(GETPOST('note', 'restricthtml')); if ($result > 0) { @@ -75,7 +82,6 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture-> { $db->begin(); - $object->fetch($id); $result = $object->delete(); if ($result > 0) { @@ -100,7 +106,6 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->facture { $db->begin(); - $object->fetch($id); if ($object->validate($user) > 0) { $db->commit(); @@ -134,7 +139,6 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->facture if ($action == 'setnum_paiement' && !empty($_POST['num_paiement'])) { - $object->fetch($id); $res = $object->update_num($_POST['num_paiement']); if ($res === 0) { @@ -146,7 +150,6 @@ if ($action == 'setnum_paiement' && !empty($_POST['num_paiement'])) if ($action == 'setdatep' && !empty($_POST['datepday'])) { - $object->fetch($id); $datepaye = dol_mktime(GETPOST('datephour', 'int'), GETPOST('datepmin', 'int'), GETPOST('datepsec', 'int'), GETPOST('datepmonth', 'int'), GETPOST('datepday', 'int'), GETPOST('datepyear', 'int')); $res = $object->update_date($datepaye); if ($res === 0) diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 76b1dab5d83..842cb24a024 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -1294,7 +1294,8 @@ class Paiement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Load the third party of object, from id into this->thirdparty + * Load the third party of object, from id into this->thirdparty. + * For payments, take the thirdparty linked to the first invoice found. This is enough because payments are done on invoices of the same thirdparty. * * @param int $force_thirdparty_id Force thirdparty id * @return int <0 if KO, >0 if OK diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php index 208d74a316f..ace21e40f95 100644 --- a/htdocs/compta/paiement/info.php +++ b/htdocs/compta/paiement/info.php @@ -36,6 +36,23 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); +$object = new Paiement($db); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$result = restrictedArea($user, $object->element, $object->id, 'paiement', ''); + +// Security check +if ($user->socid) $socid = $user->socid; +// Now check also permission on thirdparty of invoices of payments. Thirdparty were loaded by the fetch_object before based on first invoice. +// It should be enough because all payments are done on invoices of the same thirdparty. +if ($socid && $socid != $object->thirdparty->id) { + accessforbidden(); +} + + + /* * Actions */ @@ -49,8 +66,6 @@ $confirm = GETPOST('confirm', 'alpha'); llxHeader('', $langs->trans("Payment")); -$object = new Paiement($db); -$object->fetch($id, $ref); $object->info($object->id); $head = payment_prepare_head($object); diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php index 47bb2ad2582..0af202016df 100644 --- a/htdocs/compta/paiement/rapport.php +++ b/htdocs/compta/paiement/rapport.php @@ -30,9 +30,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -// Security check -if (!$user->rights->facture->lire) accessforbidden(); - $action = GETPOST('action', 'aZ09'); $socid = 0; @@ -48,6 +45,9 @@ if (!$user->rights->societe->client->voir || $socid) $dir .= '/private/'.$user-> $year = GETPOST('year', 'int'); if (!$year) { $year = date("Y"); } +// Security check +if (empty($user->rights->facture->lire)) accessforbidden(); + /* * Actions diff --git a/htdocs/compta/paiement/tovalidate.php b/htdocs/compta/paiement/tovalidate.php index f6582a4ffb4..4cf14ad8a5c 100644 --- a/htdocs/compta/paiement/tovalidate.php +++ b/htdocs/compta/paiement/tovalidate.php @@ -27,10 +27,6 @@ require '../../main.inc.php'; // Load translation files required by the page $langs->load("bills"); -// Security check -if (!$user->rights->facture->lire) - accessforbidden(); - $socid = 0; if ($user->socid > 0) { @@ -50,6 +46,9 @@ $pagenext = $page + 1; if (!$sortorder) $sortorder = "DESC"; if (!$sortfield) $sortfield = "p.rowid"; +// Security check +if (empty($user->rights->facture->lire)) accessforbidden(); + /* * Actions diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index e84a6716134..8cff096e56a 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -1029,11 +1029,10 @@ class FormCompany extends Form public function formThirdpartyType($page, $selected = '', $htmlname = 'socid', $filter = '', $nooutput = 0) { // phpcs:enable - global $langs; + global $conf, $langs; $out = ''; - if ($htmlname != "none") - { + if ($htmlname != "none") { $out .= '
'; } else { - if ($selected) - { + if ($selected) { $arr = $this->typent_array(0); $typent = $arr[$selected]; $out .= $typent; @@ -1052,7 +1050,10 @@ class FormCompany extends Form } } - if ($nooutput) return $out; - else print $out; + if ($nooutput) { + return $out; + } else { + print $out; + } } } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 4602e877bd1..9d18dd1dd85 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -165,6 +165,7 @@ function dol_verifyHash($chain, $hash, $type = '0') /** * Check permissions of a user to show a page and an object. Check read permission. * If GETPOST('action','aZ09') defined, we also check write and delete permission. + * This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user). * * @param User $user User to check * @param string $features Features to check (it must be module $object->element. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) @@ -175,20 +176,22 @@ function dol_verifyHash($chain, $hash, $type = '0') * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) * @param int $isdraft 1=The object with id=$objectid is a draft * @return int Always 1, die process if not allowed - * @see dol_check_secure_access_document() + * @see dol_check_secure_access_document(), checkUserAccessToObject() */ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0) { global $db, $conf; global $hookmanager; - //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename,$feature2,$dbt_socfield,$dbt_select"); + //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft"); //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid; //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."| '.$langs->trans('Ref').' | '; + print ' | '.$langs->trans('Ref').' | '; print $form->showrefnav($object,'id','',1,'rowid','ref'); print ' | |||
| '.$form->editfieldkey("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded')); print ' | |||||
| '.$langs->trans('PaymentMode').' | '.$labeltype; + print ' | |||||
| '.$langs->trans('PaymentMode').' | '; + print ''.$labeltype; print $object->num_payment ? ' - '.$object->num_payment : ''; print ' | |||||
| '.$form->editfieldkey("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'string','',null,$langs->trans('PaymentNumberUpdateSucceeded')); print ' | |||||
| '.$langs->trans('Amount').' | '.price($object->amount, '', $langs, 0, 0, -1, $conf->currency).' | |||||
| '.$langs->trans('Amount').' | '; + print ''.price($object->amount, '', $langs, 0, 0, -1, $conf->currency).' | |||||
| '.$langs->trans('Status').' | '.$object->getLibStatut(4).' | |||||
| '.$langs->trans('Status').' | '; + print ''.$object->getLibStatut(4).' | |||||
| '.$langs->trans('BankAccount').' | '; - print ''; + print ' | '.$langs->trans('BankAccount').' | '; + print ''; $accountstatic = new Account($db); $accountstatic->fetch($bankline->fk_account); print $accountstatic->getNomUrl(1); @@ -231,8 +245,8 @@ if ($result > 0) print ' | |||
| '.$langs->trans('BankTransactionLine').' | '; - print ''; + print ' | '.$langs->trans('BankTransactionLine').' | '; + print ''; print $bankline->getNomUrl(1, 0, 'showconciliated'); print ' | '; print '|||
| '.$form->editfieldkey("Note", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Comments", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Note", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer, 'textarea'); print ' | |||||