From cfa1b78efe3cbf4fed8f819a902e420bf58295fc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 22 Feb 2024 00:44:21 +0100 Subject: [PATCH 01/10] FIX disabled pito of menu must be greyed. --- htdocs/theme/eldy/global.inc.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 93ecd74b481..667e22a6974 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -2761,6 +2761,9 @@ a.tmenuimage:focus, .mainmenu.topmenuimage:focus { button.ui-button.ui-corner-all.ui-widget:focus { outline: none; } +.tmenuimage { + color: var(--colortextbackhmenu); +} /* For mainmenu, we always load the img */ From 3d688cfb55375f6f92fd153b8622cbfb7b2805a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 22 Feb 2024 01:13:27 +0100 Subject: [PATCH 02/10] FIX Bad picto on list of permission of a user when user not admin --- htdocs/user/perms.php | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index e30e7f19f4f..987c88d7c68 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -591,18 +591,18 @@ if ($result) { // Permission and tick (2 columns) if (!empty($object->admin) && !empty($objMod->rights_admin_allowed)) { // Permission granted because admin + print ''; if ($caneditperms) { print ''.img_picto($langs->trans("AdministratorDesc"), 'star').''; } else { - print ' '; - } - print ''; - if (!$caneditperms) { + print ''; print img_picto($langs->trans("Active"), 'switch_on', '', false, 0, 0, '', 'opacitymedium'); - //print img_picto($langs->trans("Active"), 'tick'); + print ''; } + print ''; print ''; } elseif (in_array($obj->id, $permsuser)) { // Permission granted by user + print ''; if ($caneditperms) { print ''; print 'id.'&confirm=yes&updatedmodulename='.$obj->module.'">'; @@ -610,44 +610,41 @@ if ($result) { print img_picto($langs->trans("Remove"), 'switch_on'); print ''; } else { - print ' '; - } - print ''; - if (!$caneditperms) { + print ''; print img_picto($langs->trans("Active"), 'switch_on', '', false, 0, 0, '', 'opacitymedium'); - //print img_picto($langs->trans("Active"), 'tick'); + print ''; } + print ''; print ''; } elseif (isset($permsgroupbyentitypluszero) && is_array($permsgroupbyentitypluszero)) { + print ''; if (in_array($obj->id, $permsgroupbyentitypluszero)) { // Permission granted by group print ''; print img_picto($langs->trans("Active"), 'switch_on', '', false, 0, 0, '', 'opacitymedium'); //print img_picto($langs->trans("Active"), 'tick'); print ''; - if ($caneditperms) { - print ''; - print $form->textwithtooltip($langs->trans("Inherited"), $langs->trans("PermissionInheritedFromAGroup")); - print ''; - } else { - print 'c '; - } + print ''; + print $form->textwithtooltip($langs->trans("Inherited"), $langs->trans("PermissionInheritedFromAGroup")); + print ''; } else { // Do not own permission if ($caneditperms) { - print ''; + print ''; print 'id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">'; //print img_edit_add($langs->trans("Add")); print img_picto($langs->trans("Add"), 'switch_off'); print ''; } else { - print ''; - print ' '; + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', 'opacitymedium'); print ''; } - print ' '; + print ''; + print ''; } } else { // Do not own permission + print ''; if ($caneditperms) { print ''; print 'id.'&confirm=yes&token='.newToken().'&updatedmodulename='.$obj->module.'">'; @@ -655,7 +652,7 @@ if ($result) { print img_picto($langs->trans("Add"), 'switch_off'); print ''; } else { - print 'aa'; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', 'opacitymedium'); print ''; } From 7112c5a782591fd5beaf84cf50a39222eada510d Mon Sep 17 00:00:00 2001 From: Can Arslan <138895927+mc2rcanarslan@users.noreply.github.com> Date: Wed, 21 Feb 2024 18:42:57 -0700 Subject: [PATCH 03/10] FIX: PHP Warning: Undefined variable $lib (#28342) --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ff26e87bc29..304e2ae8cc9 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -4727,7 +4727,7 @@ class Societe extends CommonObject $lib = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label'); } } - return $lib; + return $lib ?? ''; } /** From 5f9047b2e3ae2fd951a2122e4a40fe0fa3fcb40c Mon Sep 17 00:00:00 2001 From: MDW Date: Thu, 22 Feb 2024 02:45:36 +0100 Subject: [PATCH 04/10] #FIX modulenames (#28338) * Fix: modulename * Fix: modulename --- htdocs/accountancy/index.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index be739ba02fb..09236110b0e 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -290,7 +290,7 @@ if (isModEnabled('accounting')) { print $boxlist; print ''; -} elseif (isModEnabled('compta')) { +} elseif (isModEnabled('comptabilite')) { print load_fiche_titre($langs->trans("AccountancyArea"), '', 'accountancy'); print ''.$langs->trans("Module10Desc")."\n"; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 21da4633251..1cf504a30fd 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -299,7 +299,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = isModEnabled('salaries') || isModEnabled('supplier_invoice') || isModEnabled('loan') || - isModEnabled('margins') + isModEnabled('margin') ) ? 1 : 0, 'perms'=>($user->hasRight('facture', 'lire') || $user->hasRight('don', 'contact', 'lire') || $user->hasRight('tax', 'charges', 'lire') || $user->hasRight('salaries', 'read') From 288d14b7afddc6f9fa7cc38788c92c84dd548117 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 22 Feb 2024 02:58:16 +0100 Subject: [PATCH 05/10] Fix changelog --- ChangeLog | 133 +++++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b4c4aacec8..afb30c7d899 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,72 +2,6 @@ English Dolibarr ChangeLog -------------------------------------------------------------- -***** ChangeLog for 18.0.5 compared to 18.0.4 ***** -FIX: 17.0: deprecated field should only be a fallback -FIX: 17.0 - php8 warnings: test for $field existence before checking if it is null or empty -FIX: #24185: v18: display of the merged pdf lists -FIX: #26416 BOM_SUB_BOM blank page -FIX: #27166 -FIX: #27262 Recurrent invoice - user to string conversion -FIX: #27970 #26283 #27970 -FIX: Accountancy - Level 3 of binding not working on supplier side (#27462) -FIX: Accounting files export - Use th instead of td on all title columns (#28003) -FIX: add action update_extras to don card -FIX: Adding hooks init -FIX: Adding the $encode parameter to recursive _replaceHtmlWithOdtTag() utilisation -FIX: add new hook context for mo production card (#28037) -FIX: avoid from re-initializing result on nested hook getEntity (#27799) -FIX: avoid sql error (issue #26342) -FIX: bad accountancy code autoselection for supplier ventilation -FIX: Bad visible status of proposal after reopen -FIX: Barcode header cell not well displayed -FIX: BarCode Header not well displayed -FIX: Bar code verification should be done by entity because generation does (#28087) -FIX: can edit reminders on past events -FIX: check parameter socid before cloning a customer proposal (#28085) -FIX: crabe PDF is generating in conf->entity instead of object->entity -FIX: CVE-2024-23817 (#28089) -FIX: disable pointer events on jQuery-UI tooltips to prevent a glitch (fast-blinking tooltip) -FIX: Error on emailreminder not reported -FIX: Fatal error converting object of class User to string (php8) -FIX: filter by entity on contact is missing -FIX: Fix supplier invoice security check -FIX: format of color in manifest is wrong when using a custom color -FIX: #GHSA-7947-48q7-cp5m -FIX: HTML injection vulnerability in Dolibarr Application Home Page -FIX: invoice add line save devise -FIX: Keep a link to enable a 'always_enabled' module to solve pb. -FIX: label -FIX: line special_code never saved (#28051) -FIX: link to print when there is a search on multiselect fields -FIX: Menu Create of project no working on smartphone with no top menu. -FIX: missing $search_sale var (backport from v19) -FIX: Missing begin transaction when updating supplier recurring invoice -FIX: missing entity filter for check if period exists -FIX: more correctly parse the select part to be replaced in sql queries -FIX: MouvementStock::origin is not an object -FIX: notification information on intervention validated confirmation message (v17+) -FIX: not load all contacts by default when creating an event -FIX: port in Docker MailDev -FIX: propal use devise changes -FIX: public user photo not visible if $dolibarr_main_instance_unique_id -FIX: remove DISTINCT (backport from v19) -FIX: remove specific name from v19 -FIX: Retours PR -FIX: Return a better error message when token is not valid -FIX: search by ref & rowid in don list -FIX: search by thirdparty in don list -FIX: several names for one const THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT -FIX: SQL concatenation error -FIX: [TAKEPOS] display prices with or without taxes depending on setup (TAKEPOS_CHANGE_PRICE_HT) -FIX: Ternary operator condition is always true/false -FIX: too long output -FIX: Undefined property: Task::$fk_parent -FIX: uniformization to use "intervention" -FIX: Update loan.class.php (#27971) -FIX: update price extrafield on propal card -FIX: user filter in per user view of event list (#28049) -FIX: use the currency for propal signature page ***** ChangeLog for 19.0.0 compared to 18.0.0 ***** @@ -319,6 +253,73 @@ The following changes may create regressions for some external modules, but were * The load of hook context productdao has been removed before calling loadvirtualstock. Modules must use the context of main parent page or 'all' for all cases. +***** ChangeLog for 18.0.5 compared to 18.0.4 ***** +FIX: 17.0: deprecated field should only be a fallback +FIX: 17.0 - php8 warnings: test for $field existence before checking if it is null or empty +FIX: #24185: v18: display of the merged pdf lists +FIX: #26416 BOM_SUB_BOM blank page +FIX: #27166 +FIX: #27262 Recurrent invoice - user to string conversion +FIX: #27970 #26283 #27970 +FIX: Accountancy - Level 3 of binding not working on supplier side (#27462) +FIX: Accounting files export - Use th instead of td on all title columns (#28003) +FIX: add action update_extras to don card +FIX: Adding hooks init +FIX: Adding the $encode parameter to recursive _replaceHtmlWithOdtTag() utilisation +FIX: add new hook context for mo production card (#28037) +FIX: avoid from re-initializing result on nested hook getEntity (#27799) +FIX: avoid sql error (issue #26342) +FIX: bad accountancy code autoselection for supplier ventilation +FIX: Bad visible status of proposal after reopen +FIX: Barcode header cell not well displayed +FIX: BarCode Header not well displayed +FIX: Bar code verification should be done by entity because generation does (#28087) +FIX: can edit reminders on past events +FIX: check parameter socid before cloning a customer proposal (#28085) +FIX: crabe PDF is generating in conf->entity instead of object->entity +FIX: CVE-2024-23817 (#28089) +FIX: disable pointer events on jQuery-UI tooltips to prevent a glitch (fast-blinking tooltip) +FIX: Error on emailreminder not reported +FIX: Fatal error converting object of class User to string (php8) +FIX: filter by entity on contact is missing +FIX: Fix supplier invoice security check +FIX: format of color in manifest is wrong when using a custom color +FIX: #GHSA-7947-48q7-cp5m +FIX: HTML injection vulnerability in Dolibarr Application Home Page +FIX: invoice add line save devise +FIX: Keep a link to enable a 'always_enabled' module to solve pb. +FIX: label +FIX: line special_code never saved (#28051) +FIX: link to print when there is a search on multiselect fields +FIX: Menu Create of project no working on smartphone with no top menu. +FIX: missing $search_sale var (backport from v19) +FIX: Missing begin transaction when updating supplier recurring invoice +FIX: missing entity filter for check if period exists +FIX: more correctly parse the select part to be replaced in sql queries +FIX: MouvementStock::origin is not an object +FIX: notification information on intervention validated confirmation message (v17+) +FIX: not load all contacts by default when creating an event +FIX: port in Docker MailDev +FIX: propal use devise changes +FIX: public user photo not visible if $dolibarr_main_instance_unique_id +FIX: remove DISTINCT (backport from v19) +FIX: remove specific name from v19 +FIX: Retours PR +FIX: Return a better error message when token is not valid +FIX: search by ref & rowid in don list +FIX: search by thirdparty in don list +FIX: several names for one const THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT +FIX: SQL concatenation error +FIX: [TAKEPOS] display prices with or without taxes depending on setup (TAKEPOS_CHANGE_PRICE_HT) +FIX: Ternary operator condition is always true/false +FIX: too long output +FIX: Undefined property: Task::$fk_parent +FIX: uniformization to use "intervention" +FIX: Update loan.class.php (#27971) +FIX: update price extrafield on propal card +FIX: user filter in per user view of event list (#28049) +FIX: use the currency for propal signature page + ***** ChangeLog for 18.0.4 compared to 18.0.3 ***** FIX: $this->newref already exists and could have been modified by trigger but we still use a local variable for the filesystem-based renaming FIX: 16.0 only, backport fix for SQL error on global search product From 38095cf8b8aa573d062d0a2fe1a2a702ca4cdd4f Mon Sep 17 00:00:00 2001 From: HENRY Florian Date: Thu, 22 Feb 2024 13:24:18 +0100 Subject: [PATCH 06/10] fix: enabled default wharehouse field on service if STOCK_SUPPORTS_SERVICES (#28354) --- htdocs/product/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 08d86258150..c4dc0d6dcbe 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1486,7 +1486,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } - if ($type != 1 && isModEnabled('stock')) { + if (($type != 1 || getDolGlobalInt('STOCK_SUPPORTS_SERVICES')) && isModEnabled('stock')) { // Default warehouse print ''.$langs->trans("DefaultWarehouse").''; print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"'); @@ -2053,7 +2053,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } // Stock - if ($object->isProduct() && isModEnabled('stock')) { + if (($object->isProduct() || getDolGlobalInt('STOCK_SUPPORTS_SERVICES')) && isModEnabled('stock')) { // Default warehouse print ''.$langs->trans("DefaultWarehouse").''; print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"'); @@ -2557,7 +2557,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } // Default warehouse - if ($object->isProduct() && isModEnabled('stock')) { + if (($object->isProduct() || getDolGlobalInt('STOCK_SUPPORTS_SERVICES')) && isModEnabled('stock')) { $warehouse = new Entrepot($db); $warehouse->fetch($object->fk_default_warehouse); From 2a03df95b4ba756c5346c448f35f7fd0eea7f3a1 Mon Sep 17 00:00:00 2001 From: Can Arslan <138895927+mc2rcanarslan@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:17:38 -0700 Subject: [PATCH 07/10] FIX: duplicate with lines: 414-416 (#28358) --- htdocs/core/menus/init_menu_auguria.sql | 5 ----- 1 file changed, 5 deletions(-) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 5b3ee4be7ff..fee1bdc4b2c 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -415,11 +415,6 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(isModEnabled("takepos") || isModEnabled("cashdesk"))', __HANDLER__, 'left', 6100__+MAX_llx_menu__, 'bank', 'cashcontrol', 14__+MAX_llx_menu__, '/compta/cashcontrol/cashcontrol_list.php?mainmenu=bank&action=list', 'CashControl', 0, 'cashdesk', '$user->hasRight("cashdesk", "run")|| $user->hasRight("takepos", "run")', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(isModEnabled("takepos") || isModEnabled("cashdesk") && $leftmenu=="cashcontrol")', __HANDLER__, 'left', 6101__+MAX_llx_menu__, 'bank', 'cashcontrol', 6100__+MAX_llx_menu__, '/compta/cashcontrol/cashcontrol_card.php?mainmenu=bank&action=create', 'NewCashFence', 1, 'cashdesk', '$user->hasRight("cashdesk", "run")|| $user->hasRight("takepos", "run")', '', 2, 6, __ENTITY__); --- Bank - Cash control POS -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(isModEnabled("takepos") || isModEnabled("cashdesk"))', __HANDLER__, 'left', 6100__+MAX_llx_menu__, 'bank', 'cashcontrol', 14__+MAX_llx_menu__, '/compta/cashcontrol/cashcontrol_list.php?mainmenu=bank&action=list', 'CashControl', 0, 'cashdesk', '$user->hasRight("cashdesk", "run")|| $user->hasRight("takepos", "run")', '', 2, 6, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(isModEnabled("takepos") || isModEnabled("cashdesk") && $leftmenu=="cashcontrol")', __HANDLER__, 'left', 6101__+MAX_llx_menu__, 'bank', 'cashcontrol', 6100__+MAX_llx_menu__, '/compta/cashcontrol/cashcontrol_card.php?mainmenu=bank&action=create', 'NewCashFence', 1, 'cashdesk', '$user->hasRight("cashdesk", "run")|| $user->hasRight("takepos", "run")', '', 2, 6, __ENTITY__); - - -- Project insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("project")', __HANDLER__, 'left', 3600__+MAX_llx_menu__, 'project', 'projects', 7__+MAX_llx_menu__, '/projet/index.php?mainmenu=project&leftmenu=projects', 'LeadsOrProjects', 0, 'projects', '$user->hasRight("projet","lire")', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'isModEnabled("project")', __HANDLER__, 'left', 3601__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/card.php?mainmenu=project&leftmenu=projects&action=create', 'New', 1, 'projects', '$user->hasRight("projet","creer")', '', 2, 1, __ENTITY__); From 2acfea2f0c7936ce66acc72322e9dbe98c90bc45 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 23 Feb 2024 15:24:47 +0100 Subject: [PATCH 08/10] Fix corrupted data --- htdocs/install/mysql/migration/17.0.0-18.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql index 9510ca261a5..db959613bbb 100644 --- a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql +++ b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql @@ -569,3 +569,6 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HRM_EVALUATION_DELETE', 'HR Evaluation deleted', 'Executed when an evaluation is dleted', 'hrm', 4005); UPDATE llx_menu SET url = '/fourn/paiement/list.php?mainmenu=billing&leftmenu=suppliers_bills_payment' WHERE leftmenu = 'suppliers_bills_payment'; + +UPDATE llx_paiement SET ref = rowid WHERE ref IS NULL OR ref = ''; + From 7b1dc74b9e4b2068bdadb19b52e5b31ee07063e9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 23 Feb 2024 15:25:22 +0100 Subject: [PATCH 09/10] Fix corrupted data --- htdocs/install/mysql/migration/18.0.0-19.0.0.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/18.0.0-19.0.0.sql b/htdocs/install/mysql/migration/18.0.0-19.0.0.sql index c0c984332b2..c355ca25b79 100644 --- a/htdocs/install/mysql/migration/18.0.0-19.0.0.sql +++ b/htdocs/install/mysql/migration/18.0.0-19.0.0.sql @@ -40,6 +40,8 @@ ALTER TABLE llx_product_perentity ADD COLUMN pmp double(24,8); ALTER TABLE llx_projet_task ADD COLUMN fk_user_modif integer after fk_user_creat; +UPDATE llx_paiement SET ref = rowid WHERE ref IS NULL OR ref = ''; + -- v19 From d84a886e8791edb342003279d9304cb8a9a5bdbc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 23 Feb 2024 16:05:45 +0100 Subject: [PATCH 10/10] FIX #28369 --- htdocs/compta/bank/class/account.class.php | 6 +- htdocs/compta/paiement/list.php | 38 ++++++-- htdocs/fourn/paiement/list.php | 100 ++++++++++++++------- htdocs/langs/en_US/bills.lang | 1 + 4 files changed, 104 insertions(+), 41 deletions(-) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index ca542017360..d83898fc304 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -2570,12 +2570,15 @@ class AccountLine extends CommonObjectLine */ public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0) { - global $langs; + global $conf, $langs; $result = ''; $label = img_picto('', $this->picto).' '.$langs->trans("BankTransactionLine").':
'; $label .= ''.$langs->trans("Ref").': '.$this->ref; + if ($this->amount) { + $label .= '
'.$langs->trans("Amount").': '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency); + } $linkstart = ''; $linkend = ''; @@ -2587,6 +2590,7 @@ class AccountLine extends CommonObjectLine if ($withpicto != 2) { $result .= ($this->ref ? $this->ref : $this->id); } + $result .= $linkend; if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') { diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 7ac0669a28a..85c57d35385 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -183,6 +183,8 @@ if (GETPOST("orphelins", "alpha")) { $sql = "SELECT p.rowid, p.ref, p.datep, p.amount, p.statut, p.num_paiement"; $sql .= ", c.code as paiement_code"; + $sqlfields = $sql; // $sql fields to remove for count total + // Add fields from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook @@ -197,10 +199,13 @@ if (GETPOST("orphelins", "alpha")) { $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; } else { - $sql = "SELECT p.rowid, p.ref, p.datep, p.fk_bank, p.amount, p.statut, p.num_paiement"; + $sql = "SELECT p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount"; $sql .= ", c.code as paiement_code"; $sql .= ", ba.rowid as bid, ba.ref as bref, ba.label as blabel, ba.number, ba.account_number as account_number, ba.fk_accountancy_journal as accountancy_journal"; $sql .= ", s.rowid as socid, s.nom as name, s.email"; + // We need an aggregate because we added a left join to get the thirdparty. In real world, it should be the same thirdparty if payment is same (but not in database structure) + // so SUM(pf.amount) should be equal to p.amount but if we filter on $socid, it may differ + $sql .= ", SUM(pf.amount) as totalamount, COUNT(f.rowid) as nbinvoices"; // Add fields from hooks $parameters = array(); @@ -213,18 +218,21 @@ if (GETPOST("orphelins", "alpha")) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON p.fk_bank = b.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON b.fk_account = ba.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON p.rowid = pf.fk_paiement"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON pf.fk_facture = f.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; + $sql .= " WHERE p.entity IN (".getEntity('invoice').")"; if ($socid > 0) { - $sql .= " AND f.fk_soc = ".((int) $socid); + $sql .= " AND EXISTS (SELECT f.fk_soc FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."paiement_facture as pf"; + $sql .= " WHERE p.rowid = pf.fk_paiement AND pf.fk_facture = f.rowid AND f.fk_soc = ".((int) $socid).")"; } if ($userid) { if ($userid == -1) { - $sql .= " AND f.fk_user_author IS NULL"; + $sql .= " AND p.fk_user_creat IS NULL"; } else { - $sql .= " AND f.fk_user_author = ".((int) $userid); + $sql .= " AND p.fk_user_creat = ".((int) $userid); } } @@ -248,7 +256,10 @@ if (GETPOST("orphelins", "alpha")) { $sql .= natural_search('p.num_paiement', $search_payment_num); } if ($search_amount) { - $sql .= natural_search('p.amount', $search_amount, 1); + $sql .= " AND (".natural_search('p.amount', $search_amount, 1, 1); + $sql .= " OR "; + $sql .= natural_search('pf.amount', $search_amount, 1, 1); + $sql .= ")"; } if ($search_company) { $sql .= natural_search('s.nom', $search_company); @@ -270,13 +281,18 @@ if (GETPOST("orphelins", "alpha")) { $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + + $sql .= " GROUP BY p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount"; + $sql .= ", c.code"; + $sql .= ", ba.rowid, ba.ref, ba.label, ba.number, ba.account_number, ba.fk_accountancy_journal"; + $sql .= ", s.rowid, s.nom, s.email"; } // Count total nb of records $nbtotalofrecords = ''; if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(DISTINCT p.rowid) as nbtotalofrecords', $sql); $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); $resql = $db->query($sqlforcount); if ($resql) { @@ -298,6 +314,7 @@ $sql .= $db->order($sortfield, $sortorder); if ($limit) { $sql .= $db->plimit($limit + 1, $offset); } +//print $sql; $resql = $db->query($sql); if (!$resql) { @@ -532,6 +549,8 @@ while ($i < min($num, $limit)) { $object->id = $objp->rowid; $object->ref = ($objp->ref ? $objp->ref : $objp->rowid); + $object->date = $db->jdate($objp->datep); + $object->amount = $objp->amount; $companystatic->id = $objp->socid; $companystatic->name = $objp->name; @@ -629,7 +648,12 @@ while ($i < min($num, $limit)) { // Amount if (!empty($arrayfields['p.amount']['checked'])) { - print ''.price($objp->amount).''; + print ''; + if ($objp->nbinvoices > 1 || ($objp->totalamount && $objp->amount != $objp->totalamount)) { + print $form->textwithpicto('', $langs->trans("PaymentMadeForSeveralInvoices")); + } + print ''.price($objp->amount).''; + print ''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/fourn/paiement/list.php b/htdocs/fourn/paiement/list.php index 05528f2d8a1..308ac2125e6 100644 --- a/htdocs/fourn/paiement/list.php +++ b/htdocs/fourn/paiement/list.php @@ -68,6 +68,7 @@ $search_payment_type = GETPOST('search_payment_type'); $search_cheque_num = GETPOST('search_cheque_num', 'alpha'); $search_bank_account = GETPOST('search_bank_account', 'int'); $search_amount = GETPOST('search_amount', 'alpha'); // alpha because we must be able to search on '< x' +$search_sale = GETPOST('search_sale', 'int'); $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -113,6 +114,10 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); $hookmanager->initHooks(array('paymentsupplierlist')); $object = new PaiementFourn($db); +if (!$user->hasRight('societe', 'client', 'voir')) { + $search_sale = $user->id; +} + // Security check if ($user->socid) { $socid = $user->socid; @@ -176,33 +181,32 @@ $accountstatic = new Account($db); $companystatic = new Societe($db); $paymentfournstatic = new PaiementFourn($db); -$sql = 'SELECT p.rowid, p.ref, p.datep, p.amount as pamount, p.num_paiement'; -$sql .= ', s.rowid as socid, s.nom as name, s.email'; +$sql = 'SELECT p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount'; $sql .= ', c.code as paiement_type, c.libelle as paiement_libelle'; $sql .= ', ba.rowid as bid, ba.ref as bref, ba.label as blabel, ba.number, ba.account_number as account_number, ba.iban_prefix, ba.bic, ba.currency_code, ba.fk_accountancy_journal as accountancy_journal'; -if (!$user->hasRight("societe", "client", "voir")) { - $sql .= ', sc.fk_soc, sc.fk_user'; -} -$sql .= ', SUM(pf.amount)'; +$sql .= ', s.rowid as socid, s.nom as name, s.email'; +// We need an aggregate because we added a left join to get the thirdparty. In real world, it should be the same thirdparty if payment is same (but not in database structure) +// so SUM(pf.amount) should be equal to p.amount but if we filter on $socid, it may differ +$sql .= ", SUM(pf.amount) as totalamount, COUNT(f.rowid) as nbinvoices"; + +$sqlfields = $sql; // $sql fields to remove for count total $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn AS p'; -$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS pf ON p.rowid=pf.fk_paiementfourn'; -$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS f ON f.rowid=pf.fk_facturefourn'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement AS c ON p.fk_paiement = c.id'; -$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON s.rowid = f.fk_soc'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; -if (!$user->hasRight("societe", "client", "voir")) { - $sql .= ', '.MAIN_DB_PREFIX.'societe_commerciaux as sc'; + +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS pf ON p.rowid=pf.fk_paiementfourn'; +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS f ON f.rowid=pf.fk_facturefourn'; +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON s.rowid = f.fk_soc'; + +$sql .= ' WHERE f.entity IN ('.getEntity('supplier_invoice').')'; // TODO We should use p.entity that does not exists yet in this table +if ($socid > 0) { + $sql .= " AND EXISTS (SELECT f.fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf"; + $sql .= " WHERE p.rowid = pf.fk_paiementfourn AND pf.fk_facturefourn = f.rowid AND f.fk_soc = ".((int) $socid).")"; } -$sql .= ' WHERE f.entity = '.$conf->entity; -if (!$user->hasRight("societe", "client", "voir")) { - $sql .= ' AND s.rowid = sc.fk_soc AND sc.fk_user = '.((int) $user->id); -} -if ($socid > 0) { - $sql .= ' AND f.fk_soc = '.((int) $socid); -} +// Search criteria if ($search_ref) { $sql .= natural_search('p.ref', $search_ref); } @@ -217,13 +221,16 @@ if ($search_company) { $sql .= natural_search('s.nom', $search_company); } if ($search_payment_type != '') { - $sql .= " AND c.code='".$db->escape($search_payment_type)."'"; + $sql .= " AND c.code = '".$db->escape($search_payment_type)."'"; } if ($search_cheque_num != '') { $sql .= natural_search('p.num_paiement', $search_cheque_num); } if ($search_amount) { - $sql .= natural_search('p.amount', $search_amount, 1); + $sql .= " AND (".natural_search('p.amount', $search_amount, 1, 1); + $sql .= " OR "; + $sql .= natural_search('pf.amount', $search_amount, 1, 1); + $sql .= ")"; } if ($search_bank_account > 0) { $sql .= ' AND b.fk_account = '.((int) $search_bank_account); @@ -231,29 +238,48 @@ if ($search_bank_account > 0) { if ($search_all) { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } +// Search on sale representative +if ($search_sale && $search_sale != '-1') { + if ($search_sale == -2) { + $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = f.fk_soc)"; + } elseif ($search_sale > 0) { + $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = f.fk_soc AND sc.fk_user = ".((int) $search_sale).")"; + } +} // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -$sql .= ' GROUP BY p.rowid, p.ref, p.datep, p.amount, p.num_paiement, s.rowid, s.nom, s.email, c.code, c.libelle,'; +$sql .= ' GROUP BY p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount, s.rowid, s.nom, s.email, c.code, c.libelle,'; $sql .= ' ba.rowid, ba.ref, ba.label, ba.number, ba.account_number, ba.iban_prefix, ba.bic, ba.currency_code, ba.fk_accountancy_journal'; -if (!$user->hasRight("societe", "client", "voir")) { - $sql .= ', sc.fk_soc, sc.fk_user'; -} - -$sql .= $db->order($sortfield, $sortorder); +// Count total nb of records $nbtotalofrecords = ''; if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(DISTINCT p.rowid) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -$sql .= $db->plimit($limit + 1, $offset); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} +//print $sql; $resql = $db->query($sql); if (!$resql) { @@ -476,6 +502,7 @@ while ($i < min($num, $limit)) { $paymentfournstatic->id = $objp->rowid; $paymentfournstatic->ref = $objp->ref; $paymentfournstatic->datepaye = $db->jdate($objp->datep); + $paymentfournstatic->amount = $objp->amount; $companystatic->id = $objp->socid; $companystatic->name = $objp->name; @@ -493,7 +520,9 @@ while ($i < min($num, $limit)) { // Ref if (!empty($arrayfields['p.ref']['checked'])) { - print ''.$paymentfournstatic->getNomUrl(1).''; + print ''; + print $paymentfournstatic->getNomUrl(1); + print ''; if (!$i) { $totalarray['nbfield']++; } @@ -566,12 +595,17 @@ while ($i < min($num, $limit)) { // Amount if (!empty($arrayfields['p.amount']['checked'])) { - print ''.price($objp->pamount).''; + print ''; + if ($objp->nbinvoices > 1 || ($objp->totalamount && $objp->amount != $objp->totalamount)) { + print $form->textwithpicto('', $langs->trans("PaymentMadeForSeveralInvoices")); + } + print ''.price($objp->amount).''; + print ''; if (!$i) { $totalarray['nbfield']++; } $totalarray['pos'][$checkedCount] = 'amount'; - $totalarray['val']['amount'] += $objp->pamount; + $totalarray['val']['amount'] += $objp->amount; } // Buttons diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 0569c9b4b01..f5172f26ac0 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -641,3 +641,4 @@ MentionCategoryOfOperations=Category of operations MentionCategoryOfOperations0=Delivery of goods MentionCategoryOfOperations1=Provision of services MentionCategoryOfOperations2=Mixed - Delivery of goods & provision of services +PaymentMadeForSeveralInvoices=Payment made for several invoices \ No newline at end of file