From 0bd4b132a4ac6926b40553ca80d67cf0fde946de Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Wed, 10 Mar 2021 14:39:04 +0100 Subject: [PATCH 001/207] FIX : Update pencil should be shoxn only when no payment has been entered --- htdocs/compta/sociales/card.php | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 430df926859..55684a23c7d 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -444,15 +444,28 @@ if ($id > 0) { $morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1); // Employee - if ($action != 'editfk_user') { - $morehtmlref .= '
' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1); - - if (!empty($object->fk_user)) { + if($action != 'editfk_user') { + if ($object->getSommePaiement() > 0 && !empty($object->fk_user)){ $userstatic = new User($db); - $userstatic->fetch($object->fk_user); - $morehtmlref .= $userstatic->getNomUrl(1); + $result = $userstatic->fetch($object->fk_user); + if ($result > 0){ + $morehtmlref .= '
' .$langs->trans('Employee').' : '.$userstatic->getNomUrl(1); + } + } else { + $morehtmlref .= '
' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->salaries->write, 'string', '', 0, 1); + if(!empty($object->fk_user)) { + $userstatic = new User($db); + $result = $userstatic->fetch($object->fk_user); + if ($result > 0){ + $morehtmlref .= $userstatic->getNomUrl(1); + } else { + dol_print_error($db); + exit(); + } + } } } else { + $morehtmlref .= '
'.$langs->trans('Employee').' : '; $morehtmlref .= '
'; $morehtmlref .= ''; From 3a9c1613bf53baefac2afcdd688853ee3a3b2d11 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 10 Mar 2021 14:12:29 +0000 Subject: [PATCH 002/207] Fixing style errors. --- htdocs/compta/sociales/card.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 55684a23c7d..e79f4c0d0ab 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -444,19 +444,19 @@ if ($id > 0) { $morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1); // Employee - if($action != 'editfk_user') { - if ($object->getSommePaiement() > 0 && !empty($object->fk_user)){ + if ($action != 'editfk_user') { + if ($object->getSommePaiement() > 0 && !empty($object->fk_user)) { $userstatic = new User($db); $result = $userstatic->fetch($object->fk_user); - if ($result > 0){ + if ($result > 0) { $morehtmlref .= '
' .$langs->trans('Employee').' : '.$userstatic->getNomUrl(1); } } else { $morehtmlref .= '
' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->salaries->write, 'string', '', 0, 1); - if(!empty($object->fk_user)) { + if (!empty($object->fk_user)) { $userstatic = new User($db); $result = $userstatic->fetch($object->fk_user); - if ($result > 0){ + if ($result > 0) { $morehtmlref .= $userstatic->getNomUrl(1); } else { dol_print_error($db); @@ -465,7 +465,6 @@ if ($id > 0) { } } } else { - $morehtmlref .= '
'.$langs->trans('Employee').' : '; $morehtmlref .= ''; $morehtmlref .= ''; From 83b06734a22ef93b20af3a1db186b8f6689f83af Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Wed, 10 Mar 2021 15:34:43 +0100 Subject: [PATCH 003/207] FIX : Travis return --- htdocs/compta/sociales/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index e79f4c0d0ab..4b4e79ababb 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -452,7 +452,7 @@ if ($id > 0) { $morehtmlref .= '
' .$langs->trans('Employee').' : '.$userstatic->getNomUrl(1); } } else { - $morehtmlref .= '
' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->salaries->write, 'string', '', 0, 1); + $morehtmlref .= '
' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->salaries->write, 'string', '', 0, 1); if (!empty($object->fk_user)) { $userstatic = new User($db); $result = $userstatic->fetch($object->fk_user); From d2650d31cf167026d7ffcb0af6e1c42f44ae2814 Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 11 Mar 2021 09:50:05 +0100 Subject: [PATCH 004/207] add multicompany module --- htdocs/custom/multicompany/COPYING | 674 + htdocs/custom/multicompany/ChangeLog.md | 335 + htdocs/custom/multicompany/INSTALL | 16 + htdocs/custom/multicompany/README | 11 + htdocs/custom/multicompany/README.md | 36 + htdocs/custom/multicompany/README_FR | 14 + htdocs/custom/multicompany/admin/about.php | 76 + htdocs/custom/multicompany/admin/caches.php | 103 + htdocs/custom/multicompany/admin/index.html | 0 .../multicompany/admin/multicompany.php | 131 + .../admin/multicompany_extrafields.php | 115 + htdocs/custom/multicompany/admin/options.php | 494 + .../multicompany/admin/tpl/caches.tpl.php | 118 + .../multicompany/admin/tpl/card.tpl.php | 386 + .../custom/multicompany/admin/tpl/index.html | 0 .../multicompany/admin/tpl/list.tpl.php | 230 + .../multicompany/admin/tpl/switch.tpl.php | 122 + .../class/actions_multicompany.class.php | 4608 +++++ .../class/api_multicompany.class.php | 334 + .../class/dao_multicompany.class.php | 990 + htdocs/custom/multicompany/class/index.html | 0 .../custom/multicompany/class/ssp.class.php | 412 + .../multicompany/core/ajax/functions.php | 286 + .../custom/multicompany/core/ajax/index.html | 0 htdocs/custom/multicompany/core/ajax/list.php | 248 + htdocs/custom/multicompany/core/js/index.html | 0 .../custom/multicompany/core/js/lib_head.js | 214 + .../multicompany/core/login/functions_mc.php | 166 + .../custom/multicompany/core/login/index.html | 0 .../multicompany/core/modules/index.html | 0 .../core/modules/modMultiCompany.class.php | 587 + .../multicompany/core/triggers/index.html | 0 ...ulticompany_MulticompanyWorkflow.class.php | 86 + .../custom/multicompany/css/dropdown.inc.php | 199 + htdocs/custom/multicompany/css/index.html | 0 .../multicompany/css/multicompany.css.php | 355 + htdocs/custom/multicompany/img/gplv3.png | Bin 0 -> 2666 bytes htdocs/custom/multicompany/img/index.html | 0 htdocs/custom/multicompany/img/inodbox.png | Bin 0 -> 6316 bytes .../custom/multicompany/img/multicompany.png | Bin 0 -> 4380 bytes .../multicompany/img/object_multicompany.png | Bin 0 -> 1269 bytes .../img/object_multicompany_eldy.png | Bin 0 -> 972 bytes .../img/object_multicompany_md.png | Bin 0 -> 954 bytes .../buttons/css/buttons.dataTables.css | 354 + .../buttons/css/buttons.dataTables.min.css | 1 + .../inc/datatables/buttons/css/common.scss | 27 + .../inc/datatables/buttons/css/mixins.scss | 136 + .../datatables/buttons/js/buttons.colVis.js | 206 + .../buttons/js/buttons.colVis.min.js | 6 + .../datatables/buttons/js/buttons.flash.js | 1441 ++ .../datatables/buttons/js/buttons.html5.js | 1370 ++ .../buttons/js/buttons.html5.min.js | 26 + .../datatables/buttons/js/buttons.print.js | 194 + .../buttons/js/buttons.print.min.js | 4 + .../buttons/js/dataTables.buttons.js | 1705 ++ .../buttons/js/dataTables.buttons.min.js | 37 + .../inc/datatables/css/jquery.dataTables.css | 455 + .../datatables/css/jquery.dataTables.min.css | 1 + .../inc/datatables/images/sort_asc.png | Bin 0 -> 160 bytes .../datatables/images/sort_asc_disabled.png | Bin 0 -> 148 bytes .../inc/datatables/images/sort_both.png | Bin 0 -> 201 bytes .../inc/datatables/images/sort_desc.png | Bin 0 -> 158 bytes .../datatables/images/sort_desc_disabled.png | Bin 0 -> 146 bytes .../multicompany/inc/datatables/index.html | 0 .../inc/datatables/js/jquery.dataTables.js | 15345 ++++++++++++++++ .../datatables/js/jquery.dataTables.min.js | 167 + .../responsive/css/responsive.dataTables.css | 178 + .../css/responsive.dataTables.min.css | 1 + .../responsive/js/dataTables.responsive.js | 1255 ++ .../js/dataTables.responsive.min.js | 26 + htdocs/custom/multicompany/inc/index.html | 0 .../multicompany/inc/multiselect/CHANGELOG.md | 25 + .../multicompany/inc/multiselect/LICENSE | 22 + .../multicompany/inc/multiselect/README.md | 66 + .../inc/multiselect/css/bootstrap-iso.min.css | 7 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../inc/multiselect/js/bootstrap.min.js | 7 + .../inc/multiselect/js/multiselect.js | 813 + .../inc/multiselect/js/multiselect.min.js | 11 + htdocs/custom/multicompany/index.html | 0 .../langs/ca_ES/multicompany.lang | 250 + .../langs/de_AT/multicompany.lang | 250 + .../langs/de_CH/multicompany.lang | 250 + .../langs/de_DE/multicompany.lang | 250 + .../langs/en_GB/multicompany.lang | 250 + .../langs/en_US/multicompany.lang | 250 + .../langs/es_CL/multicompany.lang | 250 + .../langs/es_ES/multicompany.lang | 250 + .../langs/es_MX/multicompany.lang | 250 + .../langs/fr_FR/multicompany.lang | 250 + .../langs/hu_HU/multicompany.lang | 250 + htdocs/custom/multicompany/langs/index.html | 0 .../langs/it_IT/multicompany.lang | 250 + .../langs/nl_NL/multicompany.lang | 250 + .../langs/pt_PT/multicompany.lang | 250 + .../lib/PHP_Markdown/License.text | 36 + .../multicompany/lib/PHP_Markdown/Readme.text | 777 + .../multicompany/lib/PHP_Markdown/index.html | 0 .../lib/PHP_Markdown/markdown.php | 1732 ++ htdocs/custom/multicompany/lib/index.html | 0 .../multicompany/lib/multicompany.lib.php | 484 + .../sql/dict/init_new_entity_c_paiement.sql | 37 + .../dict/init_new_entity_c_payment_term.sql | 42 + htdocs/custom/multicompany/sql/index.html | 0 .../multicompany/sql/init_new_entity.sql | 68 + .../sql/init_new_entity_nocrypt.sql | 68 + .../multicompany/sql/llx_entity.key.sql | 23 + htdocs/custom/multicompany/sql/llx_entity.sql | 33 + .../sql/llx_entity_extrafields.sql | 26 + .../sql/llx_entity_thirdparty.key.sql | 24 + .../sql/llx_entity_thirdparty.sql | 27 + .../multicompany/sql/update_3.1.0-3.2.0.sql | 8 + .../multicompany/sql/update_3.6.0-3.7.0.sql | 14 + .../multicompany/sql/update_3.8.0-3.9.0.sql | 20 + .../multicompany/sql/update_5.0.0-6.0.0.sql | 14 + 119 files changed, 42453 insertions(+) create mode 100755 htdocs/custom/multicompany/COPYING create mode 100755 htdocs/custom/multicompany/ChangeLog.md create mode 100755 htdocs/custom/multicompany/INSTALL create mode 100755 htdocs/custom/multicompany/README create mode 100755 htdocs/custom/multicompany/README.md create mode 100755 htdocs/custom/multicompany/README_FR create mode 100755 htdocs/custom/multicompany/admin/about.php create mode 100755 htdocs/custom/multicompany/admin/caches.php create mode 100755 htdocs/custom/multicompany/admin/index.html create mode 100755 htdocs/custom/multicompany/admin/multicompany.php create mode 100755 htdocs/custom/multicompany/admin/multicompany_extrafields.php create mode 100755 htdocs/custom/multicompany/admin/options.php create mode 100755 htdocs/custom/multicompany/admin/tpl/caches.tpl.php create mode 100755 htdocs/custom/multicompany/admin/tpl/card.tpl.php create mode 100755 htdocs/custom/multicompany/admin/tpl/index.html create mode 100755 htdocs/custom/multicompany/admin/tpl/list.tpl.php create mode 100755 htdocs/custom/multicompany/admin/tpl/switch.tpl.php create mode 100755 htdocs/custom/multicompany/class/actions_multicompany.class.php create mode 100755 htdocs/custom/multicompany/class/api_multicompany.class.php create mode 100755 htdocs/custom/multicompany/class/dao_multicompany.class.php create mode 100755 htdocs/custom/multicompany/class/index.html create mode 100755 htdocs/custom/multicompany/class/ssp.class.php create mode 100755 htdocs/custom/multicompany/core/ajax/functions.php create mode 100755 htdocs/custom/multicompany/core/ajax/index.html create mode 100755 htdocs/custom/multicompany/core/ajax/list.php create mode 100755 htdocs/custom/multicompany/core/js/index.html create mode 100755 htdocs/custom/multicompany/core/js/lib_head.js create mode 100755 htdocs/custom/multicompany/core/login/functions_mc.php create mode 100755 htdocs/custom/multicompany/core/login/index.html create mode 100755 htdocs/custom/multicompany/core/modules/index.html create mode 100755 htdocs/custom/multicompany/core/modules/modMultiCompany.class.php create mode 100755 htdocs/custom/multicompany/core/triggers/index.html create mode 100755 htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php create mode 100755 htdocs/custom/multicompany/css/dropdown.inc.php create mode 100755 htdocs/custom/multicompany/css/index.html create mode 100755 htdocs/custom/multicompany/css/multicompany.css.php create mode 100755 htdocs/custom/multicompany/img/gplv3.png create mode 100755 htdocs/custom/multicompany/img/index.html create mode 100755 htdocs/custom/multicompany/img/inodbox.png create mode 100755 htdocs/custom/multicompany/img/multicompany.png create mode 100755 htdocs/custom/multicompany/img/object_multicompany.png create mode 100755 htdocs/custom/multicompany/img/object_multicompany_eldy.png create mode 100755 htdocs/custom/multicompany/img/object_multicompany_md.png create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/css/buttons.dataTables.css create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/css/buttons.dataTables.min.css create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/css/common.scss create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/css/mixins.scss create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.colVis.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.colVis.min.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.flash.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.html5.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.html5.min.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.print.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/buttons.print.min.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/dataTables.buttons.js create mode 100755 htdocs/custom/multicompany/inc/datatables/buttons/js/dataTables.buttons.min.js create mode 100755 htdocs/custom/multicompany/inc/datatables/css/jquery.dataTables.css create mode 100755 htdocs/custom/multicompany/inc/datatables/css/jquery.dataTables.min.css create mode 100755 htdocs/custom/multicompany/inc/datatables/images/sort_asc.png create mode 100755 htdocs/custom/multicompany/inc/datatables/images/sort_asc_disabled.png create mode 100755 htdocs/custom/multicompany/inc/datatables/images/sort_both.png create mode 100755 htdocs/custom/multicompany/inc/datatables/images/sort_desc.png create mode 100755 htdocs/custom/multicompany/inc/datatables/images/sort_desc_disabled.png create mode 100755 htdocs/custom/multicompany/inc/datatables/index.html create mode 100755 htdocs/custom/multicompany/inc/datatables/js/jquery.dataTables.js create mode 100755 htdocs/custom/multicompany/inc/datatables/js/jquery.dataTables.min.js create mode 100755 htdocs/custom/multicompany/inc/datatables/responsive/css/responsive.dataTables.css create mode 100755 htdocs/custom/multicompany/inc/datatables/responsive/css/responsive.dataTables.min.css create mode 100755 htdocs/custom/multicompany/inc/datatables/responsive/js/dataTables.responsive.js create mode 100755 htdocs/custom/multicompany/inc/datatables/responsive/js/dataTables.responsive.min.js create mode 100755 htdocs/custom/multicompany/inc/index.html create mode 100755 htdocs/custom/multicompany/inc/multiselect/CHANGELOG.md create mode 100755 htdocs/custom/multicompany/inc/multiselect/LICENSE create mode 100755 htdocs/custom/multicompany/inc/multiselect/README.md create mode 100755 htdocs/custom/multicompany/inc/multiselect/css/bootstrap-iso.min.css create mode 100755 htdocs/custom/multicompany/inc/multiselect/fonts/glyphicons-halflings-regular.eot create mode 100755 htdocs/custom/multicompany/inc/multiselect/fonts/glyphicons-halflings-regular.svg create mode 100755 htdocs/custom/multicompany/inc/multiselect/fonts/glyphicons-halflings-regular.ttf create mode 100755 htdocs/custom/multicompany/inc/multiselect/fonts/glyphicons-halflings-regular.woff create mode 100755 htdocs/custom/multicompany/inc/multiselect/fonts/glyphicons-halflings-regular.woff2 create mode 100755 htdocs/custom/multicompany/inc/multiselect/js/bootstrap.min.js create mode 100755 htdocs/custom/multicompany/inc/multiselect/js/multiselect.js create mode 100755 htdocs/custom/multicompany/inc/multiselect/js/multiselect.min.js create mode 100755 htdocs/custom/multicompany/index.html create mode 100755 htdocs/custom/multicompany/langs/ca_ES/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/de_AT/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/de_CH/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/de_DE/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/en_GB/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/en_US/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/es_CL/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/es_ES/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/es_MX/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/fr_FR/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/hu_HU/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/index.html create mode 100755 htdocs/custom/multicompany/langs/it_IT/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/nl_NL/multicompany.lang create mode 100755 htdocs/custom/multicompany/langs/pt_PT/multicompany.lang create mode 100755 htdocs/custom/multicompany/lib/PHP_Markdown/License.text create mode 100755 htdocs/custom/multicompany/lib/PHP_Markdown/Readme.text create mode 100755 htdocs/custom/multicompany/lib/PHP_Markdown/index.html create mode 100755 htdocs/custom/multicompany/lib/PHP_Markdown/markdown.php create mode 100755 htdocs/custom/multicompany/lib/index.html create mode 100755 htdocs/custom/multicompany/lib/multicompany.lib.php create mode 100755 htdocs/custom/multicompany/sql/dict/init_new_entity_c_paiement.sql create mode 100755 htdocs/custom/multicompany/sql/dict/init_new_entity_c_payment_term.sql create mode 100755 htdocs/custom/multicompany/sql/index.html create mode 100755 htdocs/custom/multicompany/sql/init_new_entity.sql create mode 100755 htdocs/custom/multicompany/sql/init_new_entity_nocrypt.sql create mode 100755 htdocs/custom/multicompany/sql/llx_entity.key.sql create mode 100755 htdocs/custom/multicompany/sql/llx_entity.sql create mode 100755 htdocs/custom/multicompany/sql/llx_entity_extrafields.sql create mode 100755 htdocs/custom/multicompany/sql/llx_entity_thirdparty.key.sql create mode 100755 htdocs/custom/multicompany/sql/llx_entity_thirdparty.sql create mode 100755 htdocs/custom/multicompany/sql/update_3.1.0-3.2.0.sql create mode 100755 htdocs/custom/multicompany/sql/update_3.6.0-3.7.0.sql create mode 100755 htdocs/custom/multicompany/sql/update_3.8.0-3.9.0.sql create mode 100755 htdocs/custom/multicompany/sql/update_5.0.0-6.0.0.sql diff --git a/htdocs/custom/multicompany/COPYING b/htdocs/custom/multicompany/COPYING new file mode 100755 index 00000000000..94a9ed024d3 --- /dev/null +++ b/htdocs/custom/multicompany/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/htdocs/custom/multicompany/ChangeLog.md b/htdocs/custom/multicompany/ChangeLog.md new file mode 100755 index 00000000000..c1860df345f --- /dev/null +++ b/htdocs/custom/multicompany/ChangeLog.md @@ -0,0 +1,335 @@ +# ChangeLog MULTICOMPANY + +## 12.0.1 + +NEW add stock warehouse sharing list +NEW add triggers create, update, delete +FIX uniformize trigger +FIX uniformize extrafields management + +## 12.0.0 + +FIX compatibility with Dolibarr 12 +FIX look and feel V12 + +## 11.0.2 + +NEW add stock warehouse sharing list + +## 11.0.1 + +FIX form is not printed to addgroups on user card in Dolibarr 11.0 + +## 11.0.0 + +FIX compatibility with Dolibarr 11 +FIX better warning for upgrade message + +## 10.0.3 + +NEW add templates of entities management +NEW pre-format modules and shares of new entities with templates +NEW possibility to duplicate usergroup rights by entities in transversal mode +NEW add label of current entity in right top menu + +## 10.0.1.3 + +FIX compatibility with Two-Factor Authentication module + +## 10.0.1.2 + +FIX missing rename facture ref field (ref instead facnumber) + +## 10.0.1.1 + +FIX wrong Font Awesome css class for check/uncheck button + +## 10.0.1 + +FIX wrong sql request for show users in transversal mode + +## 10.0.0 + +NEW add dropdown menu (look and feel v10) +NEW change logo and background of entity in login page +FIX compatibility with Dolibarr 10 + +## 9.0.4 + +FIX wrong sql request for show users in transversal mode + +## 9.0.3 + +FIX display rights of allowed entity for user when it's not entity 1 on perms card + +## 9.0.2 + +FIX better test for compatibility with multiple Dolibarr versions + +## 9.0.1 + +FIX superadmin can always edit groups of another entities +FIX need php 5.6 min +FIX possibility to hide html title with constant MULTICOMPANY\_HIDE\_HTML\_TITLE +FIX translation + +## 9.0.0 + +NEW add customer invoices sharing +NEW add proposal numbering sharing +NEW an external plugin can easily include its own sharing settings +NEW add buttons to stay in entity card +FIX compatibility between proposal sharing and proposalnumber sharing +FIX compatibility between invoice sharing and invoicenumber sharing +FIX possibility to use a different referrer for numbering sharing +FIX compatibility with Dolibarr 9 + +## 8.0.6 + +FIX backport from newest version for avoid error + +## 8.0.5.4 + +FIX display rights of allowed entity for user when it's not entity 1 on perms card + +## 8.0.5.3 + +FIX Make retrocompatibility for external modules using old method + +## 8.0.5.2 + +FIX when using switchentityautoopen, this avoid to have the autopen always after first use + +## 8.0.5.1 + +FIX missing cashdesk module authentication + +## 8.0.5 + +FIX better check entities in user permissions tab + +## 8.0.4 + +FIX autoopen of the "switch entity popup" was broken (used by DoliDroid) +FIX version checking refactorization + +## 8.0.3 + +FIX missing "printUserPasswordField" hook for mc authentication + +## 8.0.2 + +FIX use POST instead GET for avoid false positive error with firewall (datatables) +FIX avoid error when SHMOP cache is used + +## 8.0.1 + +FIX Look and feel v8 + +## 8.0.0 + +NEW can share leave requests - holidays +NEW ad possibility to change third party entity +NEW add customer proposals sharing with read/write permissions +NEW add read/write permissions for products/services sharing +NEW add entity field in products/services list +NEW add entity field in third parties list +NEW add entity field in customer proposals list +NEW add entity information in banner of elements sharing +NEW add warning message when hide the entity in login page +NEW add warning message if user not linked with group/entity (transversal mode) +NEW change icons add specific icon by theme +NEW Can set a parameter switchentityautoopen=1 on any urls to force open of the switch entity box, with no need to click: +- This is required to provide a compatibility with native android application when menu is not managed by Dolibarr but by the android application + +NEW change multiselect library +NEW add product reseller prices sharing +NEW add new parameters for enable and make visible an entity by default + +FIX compatibility with Dolibarr 8 +FIX better redirection when you switch to another entity +FIX better user/group management in transversal mode +FIX many improvements and fixes for look and performance + +## 7.0.4 + +FIX use POST instead GET for avoid false positive error with firewall (datatables) +FIX avoid error when SHMOP cache is used + +## 7.0.3 + +Fix: datatables error when "multicompany" directory is in root of dolibarr +Fix: use REQUEST_URI by default when switch to another entity +Fix: use dol_include_once() by default + +## 7.0.2 + +Fix: broken feature when dropdown list in login page is hidden + +## 7.0.1 + +Fix: hide dictionnaries sharings for the moment + +## 7.0.0 + +Fix: compatibility with Dolibarr 7 +New: add cache system (memcached) +New: use datatables for entities list +New: add multiselect entities for rights management in transverse mode + +## 6.0.1 + +Fix: compatibility with Dolibarr 7 + +## 6.0.0 + +Fix: compatibility with Dolibarr 6 +New: add members sharing +New: add possibility to customizing dictionnaries by entity (llx\_c\_paiement and llc\_c\_payment\_term) +New: getEntity function use true $shared value by default +New: big refactorization of transverse mode + +Improvements to the transverse mode: +- A module activated in the main entity is no longer activated in the child entities, each entity can have its own modules activated. +- You can define different rights per entity in the same group. +- You can customize/supplement the rights of a user by entity + +For developers: +* You can remove $multicompany_transverse_mode in conf.php +* Use $conf->global->MULTICOMPANY\_TRANSVERSE\_MODE instead $conf->multicompany->transverse_mode +* Use getEntity('xxx') instead getEntity('xxx', 1) and use getEntity('xxx', 0) instead getEntity('xxx') +* Use getEntity('thirdparty') instead getEntity('societe') +* Use getEntity('member') instead getEntity('adherent') +* Use getEntity('bankaccount') instead getEntity('bank_account') + +## 5.0.0 + +Fix: compatibility with Dolibarr 5 +New: add expense report sharing + +## 4.0.0 + +Fix: compatibility with Dolibarr 4 +New: add project sharing + +## 3.8.2 + +Fix: compatibility with transverse modes + +## 3.8.1 + +Fix: folder sharing was not working when more than 2 entities + +## 3.8.0 + +Fix: compatibility with Dolibarr 3.8.x + +## 3.7.3 + +Fix: folder sharing was not working when more than 2 entities + +## 3.7.2 + +New: add transifex management +New: change the development platform + +## 3.7.1 + +New: add extrafields +Fix: more bugs + +## 3.7.0 + +Fix: compatibility with Dolibarr 3.7.x +New: add invoice number sharing +New: add script to move master entity with another entity +New: add about page + +## 3.6.2 + +Fix: folder sharing was not working when more than 2 entities + +## 3.6.1 + +Fix: add stock sharing parameters + +## 3.6.0 + +Fix: compatibility with Dolibarr 3.6.x +Fix: show entities combobox only in transverse mode or with admin users +Fix: automatic connection to the entity of the user if the drop down list of entities is hidden (use different login strictly by entity) +New: add multicompany function login + +## 3.5.0 + +Fix: compatibility with Dolibarr 3.5.0 + +## 3.4.0 + +New: add bank sharing +New: add product prices sharing +New: add agenda sharing +New: add stock sharing +New: add Hungary translation +Fix: compatibility with Dolibarr 3.4 +Fix: grant access for user card in transverse mode +Fix: sharing services was not functional if the module product was not activated +Fix: more bugs + +## 3.2.2 + +New: add Netherland translation +Fix: minor bugs and uniformize code +Fix: add check method for login +Fix: check permission in combobox +Fix: remove constantes already defined by module +Fix: compatibility with bureau2crea theme +Fix: possibility to force entity un login page +Fix: bad rights verification + +## 3.2.1 + +no release + +## 3.2.0 + +New: add sharing system for products/services and thirdparties/contacts between entities +New: add category sharing between entities +Fix: problem with user card access and wrong carriage return +Fix: show login page options with hook manager +Fix: update es\_ES and ca\_ES translations +Fix: replace serialize by json +Fix: security +Fix: more bugs + +## 3.1.2 + +Fix: invalid path if you do not use the custom directory + +## 3.1.1 + +Fix: convert current admin to superadmin +The administrator of the primary entity was not converted into superadministrator when activating the module, +this happened during an update of a version of Dolibarr < 3.1 to >= 3.1 + +## 3.1.0 + +New: change logo +New: add italian translation +New: stay connected for switch entity +New: add options tab in module configuration +New: possibility to hide combobox in login page +New: add transverse mode +* Off mode: The rights and groups are managed in each entity: users belong to the entity for their rights +* One mode: Groups can only belong to the entity = 0 and that the user belongs to a particular entity + +Fix: translation + +## 3.0.1 + +New: add spanish translation +Fix: minor bugfix + +## 3.0.0 + +First release of this module diff --git a/htdocs/custom/multicompany/INSTALL b/htdocs/custom/multicompany/INSTALL new file mode 100755 index 00000000000..7e987f02a8f --- /dev/null +++ b/htdocs/custom/multicompany/INSTALL @@ -0,0 +1,16 @@ +INSTALL +------- + +Since version 3 it is possible to define an alternative root directory, +This allows you to store, same place, plug-ins and custom templates. +Just create a directory at the root of Dolibarr (eg custom), +then declare it in the file conf.php : + +examples : + +$dolibarr_main_url_root='http://myserver'; +$dolibarr_main_document_root='/path/of/dolibarr/htdocs'; +$dolibarr_main_url_root_alt='/custom'; +$dolibarr_main_document_root_alt='/path/of/dolibarr/htdocs/custom'; + +Copy "multicompany" directory to the root of "custom" directory. diff --git a/htdocs/custom/multicompany/README b/htdocs/custom/multicompany/README new file mode 100755 index 00000000000..6e822ca85b6 --- /dev/null +++ b/htdocs/custom/multicompany/README @@ -0,0 +1,11 @@ +Thank you for your contribution + +Developer: +Régis Houssin +https://www.inodbox.com + +Development platform: +https://git.framasoft.org/inodbox/multicompany + +Translation platform: +https://www.transifex.com/inodbox/multicompany/ diff --git a/htdocs/custom/multicompany/README.md b/htdocs/custom/multicompany/README.md new file mode 100755 index 00000000000..d453b59fca2 --- /dev/null +++ b/htdocs/custom/multicompany/README.md @@ -0,0 +1,36 @@ +Module for Multi-Company Management +========= + +This module enables multi-company to handle multiple entities on a single installation Dolibarr. + +The sharing of the base product, customer base/contacts and user base and more... + +This module required Dolibarr >= 9.0.0 stable installation + +Thank you for your contribution + +Contact +-------- +This module is developped by Régis Houssin () + +Website: +www.inodbox.com + +Heypster french social network: +iNodbox + +Development platform: +git.framasoft.org/inodbox/multicompany/ + +Translation platform: +www.transifex.com/inodbox/multicompany/ + +Licence +------- +GPLv3 or (at your option) any later version. + +See COPYING for more information. + +Other Licences +-------------- +Uses Michel Fortin's PHP Markdown Licensed under BSD to display this README. diff --git a/htdocs/custom/multicompany/README_FR b/htdocs/custom/multicompany/README_FR new file mode 100755 index 00000000000..6b22b2f1f37 --- /dev/null +++ b/htdocs/custom/multicompany/README_FR @@ -0,0 +1,14 @@ +Merci pour votre contribution + +Développeur : +Régis Houssin +https://www.inodbox.com + +Heypster réseau social français +https://www.heypster.com/fr/profile/21956 + +Plateforme de développement : +https://git.framasoft.org/inodbox/multicompany + +Plateforme de traduction : +https://www.transifex.com/inodbox/multicompany/ \ No newline at end of file diff --git a/htdocs/custom/multicompany/admin/about.php b/htdocs/custom/multicompany/admin/about.php new file mode 100755 index 00000000000..d9137aaadea --- /dev/null +++ b/htdocs/custom/multicompany/admin/about.php @@ -0,0 +1,76 @@ + + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file /multicompany/admin/about.php + * \ingroup multicompany + * \brief About Page + */ + +$res=@include("../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../main.inc.php"); // For "custom" directory + + +// Libraries +dol_include_once('/multicompany/lib/multicompany.lib.php'); +dol_include_once('/multicompany/lib/PHP_Markdown/markdown.php'); + +// Translations +$langs->loadLangs(array('admin', 'multicompany@multicompany')); + +// Security check +if (empty($user->admin) || ! empty($user->entity)) { + accessforbidden(); +} + +/* + * View + */ + +$help_url='EN:Module_MultiCompany|FR:Module_MultiSociété'; +llxHeader('', $langs->trans("Module5000Name"), $help_url); + +// Subheader +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("MultiCompanySetup"), $linkback, 'multicompany@multicompany',0,'multicompany_title'); + +// Configuration header +$head = multicompany_prepare_head(); +dol_fiche_head($head, 'about', $langs->trans("Module5000Name")); + +// About page goes here + +$buffer = file_get_contents(dol_buildpath('/multicompany/README.md',0)); +print Markdown($buffer); + +print '
'; + +$url = 'https://www.inodbox.com/'; +$link = 'iNodbox'; +print $langs->trans("MulticompanyMoreModules", $link).'

'; +print ''; +print '


'; + +print ''; + +dol_fiche_end(); + +llxFooter(); + +$db->close(); diff --git a/htdocs/custom/multicompany/admin/caches.php b/htdocs/custom/multicompany/admin/caches.php new file mode 100755 index 00000000000..8d7735c92f9 --- /dev/null +++ b/htdocs/custom/multicompany/admin/caches.php @@ -0,0 +1,103 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file /multicompany/admin/options.php + * \ingroup multicompany + * \brief Page to setup options for Multicompany module + */ + + +$res=@include("../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../main.inc.php"); // For "custom" directory + +dol_include_once('/multicompany/lib/multicompany.lib.php'); +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; + +$langs->loadLangs(array('admin', 'multicompany@multicompany')); + +// Security check +if (empty($user->admin) || ! empty($user->entity)) { + accessforbidden(); +} + +$action = GETPOST('action','alpha'); + + +/* + * Action + */ + +if ($action == 'setvalue') +{ + $result=dolibarr_set_const($db, "MULTICOMPANY_MEMCACHED_SERVER",GETPOST('MULTICOMPANY_MEMCACHED_SERVER', 'alpha'),'chaine',0,'',0); + + if ($result >= 0) + { + setEventMessage($langs->trans("SetupSaved")); + + // Force new value + $conf->global->MULTICOMPANY_MEMCACHED_SERVER=GETPOST('MULTICOMPANY_MEMCACHED_SERVER', 'alpha'); + } + else + { + dol_print_error($db); + } +} + + +/* + * View + */ + +$form=new Form($db); + +$arrayofjs=array( + '/multicompany/core/js/lib_head.js' +); + +$help_url='EN:Module_MultiCompany|FR:Module_MultiSociété'; +llxHeader('', $langs->trans("MultiCompanySetup"), $help_url, '', '', '', $arrayofjs); + + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("MultiCompanySetup"),$linkback,'multicompany@multicompany',0,'multicompany_title'); + +$head=multicompany_prepare_head(); +dol_fiche_head($head, 'caches', $langs->trans("ModuleSetup"), -1); + +print '
'.info_admin($langs->trans("MulticompanyCacheSystemInfo"), 0, 0, '1', 'clearboth').'
'; + +print ''; +print ''; +print ''; + +dol_include_once('/multicompany/admin/tpl/caches.tpl.php'); + +print ''; + +// Boutons actions +print '
'; +print ''; +print ''."\n"; +print '
'; + +llxFooter(); +$db->close(); diff --git a/htdocs/custom/multicompany/admin/index.html b/htdocs/custom/multicompany/admin/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/admin/multicompany.php b/htdocs/custom/multicompany/admin/multicompany.php new file mode 100755 index 00000000000..d1d6ace4054 --- /dev/null +++ b/htdocs/custom/multicompany/admin/multicompany.php @@ -0,0 +1,131 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file multicompany/admin/multicompany.php + * \ingroup multicompany + * \brief Page d'administration/configuration du module Multi-societe + */ + +$res=@include("../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../main.inc.php"); // For "custom" directory + +dol_include_once('/multicompany/class/actions_multicompany.class.php', 'ActionsMulticompany'); +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; + +$langs->loadLangs(array('admin', 'languages', 'multicompany@multicompany')); + +if (! $user->admin || $user->entity) { + accessforbidden(); +} + +$action=GETPOST('action', 'alpha'); + +$object = new ActionsMulticompany($db); + +$form=new Form($db); +$formadmin=new FormAdmin($db); +$formcompany=new FormCompany($db); + +/* + * Actions + */ + +$object->doAdminActions($action); + +//$test = new DaoMulticompany($db); +//$test->deleteEntityRecords(4); + +/* + * View + */ + +$extrajs=''; +$extracss=''; + +if (empty($action) || $action == "update" || $action == "add") { + $extrajs = array( + '/multicompany/inc/datatables/js/jquery.dataTables.min.js', + //'/multicompany/inc/datatables/responsive/js/dataTables.responsive.min.js', + '/multicompany/inc/datatables/buttons/js/dataTables.buttons.min.js', + '/multicompany/inc/datatables/buttons/js/buttons.colVis.min.js', + '/multicompany/inc/datatables/buttons/js/buttons.html5.min.js' + ); + $extracss = array( + '/multicompany/inc/datatables/css/jquery.dataTables.min.css', + //'/multicompany/inc/datatables/responsive/css/responsive.dataTables.min.css', + '/multicompany/inc/datatables/buttons/css/buttons.dataTables.min.css' + ); +} else if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) { + $extrajs = array( + '/multicompany/inc/multiselect/js/multiselect.min.js', + //'/multicompany/inc/multiselect/js/multiselect.js' + ); + $extracss = array( + '/multicompany/inc/multiselect/css/bootstrap-iso.min.css' + ); +} + +$help_url='EN:Module_MultiCompany|FR:Module_MultiSociété'; +llxHeader('', $langs->trans("MultiCompanySetup"), $help_url, '', '', '', $extrajs, $extracss); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("MultiCompanySetup"), $linkback, 'multicompany@multicompany', 0, 'multicompany_title'); + +$head = multicompany_prepare_head(); +dol_fiche_head($head, 'entities', $object->getTitle($action), -1); + +$level = checkMultiCompanyVersion(); +if ($level === 1 || $level === -1) +{ + $text = $langs->trans("MultiCompanyIsOlderThanDolibarr"); + if ($level === -1) $text = $langs->trans("DolibarrIsOlderThanMulticompany"); + + print '
'; + dol_htmloutput_mesg($text, '', 'warning', 1); + print '
'; + +} + +// Assign template values +$object->assign_values($action); + +// Isolate Boostrap for avoid conflicts +if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED) && ! empty($action) && $action != "update" && $action != "add") { + print '
'; +} + +// Show the template +$object->display(); + +// Isolate Boostrap for avoid conflicts +if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED) && ! empty($action) && $action != "update" && $action != "add") { + print '
'; +} + +// Card end +dol_fiche_end(); +// Footer +llxFooter(); +// Close database handler +$db->close(); diff --git a/htdocs/custom/multicompany/admin/multicompany_extrafields.php b/htdocs/custom/multicompany/admin/multicompany_extrafields.php new file mode 100755 index 00000000000..91a8d5f4081 --- /dev/null +++ b/htdocs/custom/multicompany/admin/multicompany_extrafields.php @@ -0,0 +1,115 @@ + + * Copyright (C) 2016-2020 Regis Houssin + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file multicompany/admin/multicompany.php + * \ingroup multicompany + * \brief Page to setup extra fields of entities + */ + +// Dolibarr environment +$res=@include("../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../main.inc.php"); // For "custom" directory + +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; +dol_include_once('/multicompany/lib/multicompany.lib.php'); + +// Security check +if (empty($user->admin) || ! empty($user->entity)) { + accessforbidden(); +} + +$langs->loadLangs(array('admin', 'other')); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label = ExtraFields::$type2label; +$type2label = array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key] = $langs->transnoentitiesnoconv($val); + +$action = GETPOST('action', 'alpha'); +$attrname = GETPOST('attrname', 'alpha'); +$elementtype = 'entity'; // Must be the $table_element of the class that manage extrafield + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT . '/core/actions_extrafields.inc.php'; + + +/* + * View + */ + +$textobject = $langs->transnoentitiesnoconv("Entities"); + +$help_url='EN:Module_MultiCompany|FR:Module_MultiSociété'; +llxHeader('', $langs->trans("MultiCompanySetup"), $help_url); + +$linkback = '' . $langs->trans("BackToModuleList") . ''; +print load_fiche_titre($langs->trans("MultiCompanySetup"), $linkback, 'multicompany@multicompany',0,'multicompany_title'); + +// Configuration header +$head = multicompany_prepare_head(); +dol_fiche_head($head, 'attributes', $langs->trans("ModuleSetup"), -1); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +dol_fiche_end(); + +// Buttons +if ($action != 'create' && $action != 'edit') { + print ''; +} + +/* ************************************************************************* */ +/* */ +/* Creation d'un champ optionnel */ +/* */ +/* ************************************************************************** */ + +if ($action == 'create') { + print "
"; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT . '/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************* */ +/* */ +/* Edition d'un champ optionnel */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) { + print "
"; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT . '/core/tpl/admin_extrafields_edit.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/custom/multicompany/admin/options.php b/htdocs/custom/multicompany/admin/options.php new file mode 100755 index 00000000000..806a45caf6d --- /dev/null +++ b/htdocs/custom/multicompany/admin/options.php @@ -0,0 +1,494 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file multicompany/admin/parameters.php + * \ingroup multicompany + * \brief Page d'administration/configuration du module Multi-Company + */ + +$res=@include("../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../main.inc.php"); // For "custom" directory + +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; +dol_include_once('/multicompany/class/actions_multicompany.class.php', 'ActionsMulticompany'); + +$langs->loadLangs(array('admin', 'multicompany@multicompany')); + +// Security check +if (empty($user->admin) || ! empty($user->entity)) { + accessforbidden(); +} + +$action=GETPOST('action','alpha'); + +$object = new ActionsMulticompany($db); + + +/* + * Action + */ + + +/* + * View + */ + +$extrajs = array( + '/multicompany/core/js/lib_head.js' +); + +$help_url='EN:Module_MultiCompany|FR:Module_MultiSociété'; +llxHeader('', $langs->trans("MultiCompanySetup"), $help_url,'','','',$extrajs); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("MultiCompanySetup"),$linkback,'multicompany@multicompany',0,'multicompany_title'); + +$head = multicompany_prepare_head(); +dol_fiche_head($head, 'options', $langs->trans("ModuleSetup"), -1); + +$level = checkMultiCompanyVersion(); +if ($level === 1 || $level === -1) +{ + $text = $langs->trans("MultiCompanyIsOlderThanDolibarr"); + if ($level === -1) $text = $langs->trans("DolibarrIsOlderThanMulticompany"); + + print '
'; + dol_htmloutput_mesg($text, '', 'warning', 1); + print '
'; + +} + +$form=new Form($db); + +$hidden=true; +$checkconfig = checkMulticompanyAutentication(); +if ($checkconfig !== true) { + if (! empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)) { + $hidden=false; + } + print ''; +} else { + if (empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)) { + $hidden=false; + } + print ''; +} + +print ''; +print ''; +print ''."\n"; +print ''; +print ''."\n"; +print ''; + +/* + * System parameters + */ + +// Login page combobox activation +print ''; +print ''; +print ''; +print ''; + +// Replace entity logo in login page +print 'global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX) ? ' style="display:none;"' : '').'>'; +print ''; +print ''; + +print ''; + +// Replace entity background in login page +print 'global->MULTICOMPANY_LOGIN_LOGO_BY_ENTITY) ? ' style="display:none;"' : '').'>'; +print ''; +print ''; +print ''; + +// Disable the new dropdown menu +print ''; +print ''; +print ''; +print ''; + +// Hide/View top menu entity label +print ''; +print ''; +print ''; +print ''; + +// Active by default during create +print ''; +print ''; +print ''; +print ''; + +// Visible by default during create +print 'global->MULTICOMPANY_ACTIVE_BY_DEFAULT) ? ' style="display:none;"' : '').'>'; +print ''; +print ''; +print ''; + +// Template management +$text = img_picto('', 'info','class="linkobject"'); +$htmltext = $langs->trans("TemplateOfEntityManagementInfo"); + +print ''; +print ''; +print ''; +print ''; + +/* + * Sharings parameters + */ +print ''; +print ''."\n"; +print ''; +print ''."\n"; +print ''; + +/* Mode de gestion des droits : + * Mode Off : mode Off : pyramidale. Les droits et les groupes sont gérés dans chaque entité : les utilisateurs appartiennent au groupe de l'entity pour obtenir leurs droits + * Mode On : mode On : transversale : Les groupes ne peuvent appartenir qu'a l'entity = 0 et c'est l'utilisateur qui appartient à tel ou tel entity + */ + +$text = img_picto('', 'info','class="linkobject"'); +$htmltext = $langs->trans("GroupModeTransversalInfoFull"); + +print ''; +print ''; +print ''; + +print ''; + +// Enable global sharings +if (! empty($conf->societe->enabled) + || ! empty($conf->product->enabled) + || ! empty($conf->service->enabled) + || ! empty($conf->categorie->enabled) + || ! empty($conf->adherent->enabled) + || ! empty($conf->agenda->enabled)) +{ + print ''; + print ''; + print ''; + + print ''; +} + +$text = img_picto('', 'info','class="linkobject"'); +$htmltext = $langs->trans("GlobalSharingsInfo"); + +print 'global->MULTICOMPANY_SHARINGS_ENABLED) ? ' style="display:none;"' : '').'>'; +print ''."\n"; +print ''; +print ''."\n"; +print ''; + +// Share thirparties and contacts +if (! empty($conf->societe->enabled)) +{ + print 'global->MULTICOMPANY_SHARINGS_ENABLED) ? ' style="display:none;"' : '').'>'; + print ''; + print ''; + + print ''; +} + +// Elements sharings +$text = img_picto('', 'info','class="linkobject"'); + +foreach ($object->sharingelements as $element => $params) +{ + if (! isset($params['disable']) && $params['type'] === 'element') + { + $tooltip = null; + $display = ! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED); + $module = ((isset($object->sharingmodulename[$element]) && !empty($object->sharingmodulename[$element])) ? $object->sharingmodulename[$element] : $element); + $enabled = (! empty($params['enable']) ? dol_eval($params['enable'], 1) : $conf->$module->enabled); + if (! empty($enabled)) + { + $icon = (! empty($params['icon'])?$params['icon']:'cogs'); + + if (! empty($params['lang'])) { + $langs->load($params['lang']); + } + + if (! empty($params['tooltip'])) { + $htmltext = $langs->trans($params['tooltip']); + $tooltip = $form->textwithtooltip('', $htmltext, 2, 1, $text); + } + + if (! empty($params['display'])) { + $display = ($display && dol_eval($params['display'], 1)); + } + + $display = ($display ? '' : ' style="display:none;"'); + + print ''; + print ''; + print ''; + + print ''; + } + } +} + +// Objects sharings +$text = img_picto('', 'info','class="linkobject"'); +$htmltext = $langs->trans("ObjectSharingsInfo"); +$display=(! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED) && ! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) ? '' : ' style="display:none;"'); +print ''; +print ''."\n"; +print ''; +print ''."\n"; +print ''; + +foreach ($object->sharingelements as $element => $params) +{ + if (! isset($params['disable']) && ($params['type'] === 'object' || $params['type'] === 'objectnumber')) + { + $tooltip = null; + $display = ! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED); + $module = ((isset($object->sharingmodulename[$element]) && !empty($object->sharingmodulename[$element])) ? $object->sharingmodulename[$element] : $element); + $enabled = (! empty($params['enable']) ? dol_eval($params['enable'], 1) : $conf->$module->enabled); + if (! empty($enabled)) + { + $icon = (! empty($params['icon'])?$params['icon']:'cogs'); + + if (! empty($params['lang'])) { + $langs->load($params['lang']); + } + + if (! empty($params['tooltip'])) { + $htmltext = $langs->trans($params['tooltip']); + $tooltip = $form->textwithtooltip('', $htmltext, 2, 1, $text); + } + + if (! empty($params['display'])) { + $display = ($display && dol_eval($params['display'], 1)); + } + + $display = ($display ? '' : ' style="display:none;"'); + + print ''; + print ''; + print ''; + + print ''; + } + } +} + +// Dictionnaries +if (1==2 && ! empty($object->sharingdicts)) +{ + $text = img_picto('', 'info','class="linkobject"'); + $htmltext = $langs->trans("DictsSharingsInfo"); + + print ''; + print ''."\n"; + print ''; + print ''."\n"; + print ''; + + foreach ($object->sharingdicts as $dict => $data) + { + print ''; + print ''; + print ''; + + print ''; + } +} + +print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("HideLoginCombobox").' '; +if ($checkconfig !== true) { + $input = array( + 'showhide' => array( + '#mc_hide_login_combobox_error' + ) + ); +} else { + $input = array( + 'hideshow' => array( + '#dol_hide_login_combobox_error' + ) + ); +} +$input['hideshow'][] = '#changeloginlogo'; +$input['hideshow'][] = '#changeloginbackground'; +$input['del'] = array('MULTICOMPANY_LOGIN_LOGO_BY_ENTITY', 'MULTICOMPANY_LOGIN_BACKGROUND_BY_ENTITY'); +print ajax_mcconstantonoff('MULTICOMPANY_HIDE_LOGIN_COMBOBOX', $input, 0); +print '
'.$langs->trans("EntityBackgroundInLoginPage").' '; +print ajax_mcconstantonoff('MULTICOMPANY_LOGIN_BACKGROUND_BY_ENTITY', '', 0); +print '
'.$langs->trans("DisableSwitchEntityDropdownMenu").' '; +$input = array( + 'reload' => true +); +print ajax_mcconstantonoff('MULTICOMPANY_DROPDOWN_MENU_DISABLED', $input, 0); +print '
'.$langs->trans("ShowTopMenuEntityLabel").' '; +$input = array( + 'reload' => true +); +print ajax_mcconstantonoff('MULTICOMPANY_NO_TOP_MENU_ENTITY_LABEL', $input, 0, 1); +print '
'.$langs->trans("EntityActiveByDefault").' '; +$input = array( + 'showhide' => array( + '#visiblebydefault' + ), + 'del' => array( + 'MULTICOMPANY_VISIBLE_BY_DEFAULT' + ) +); +print ajax_mcconstantonoff('MULTICOMPANY_ACTIVE_BY_DEFAULT', $input, 0); +print '
'.$langs->trans("EntityVisibleByDefault").' '; +print ajax_mcconstantonoff('MULTICOMPANY_VISIBLE_BY_DEFAULT', '', 0); +print '
'.$langs->trans("TemplateOfEntityManagement").' '.$form->textwithtooltip('',$htmltext,2,1,$text).' '; +print ajax_mcconstantonoff('MULTICOMPANY_TEMPLATE_MANAGEMENT', '', 0); +print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("GroupModeTransversal").' '.$form->textwithtooltip('',$htmltext,2,1,$text).' '; +$input = array( + 'alert' => array( + 'set' => array( + 'info' => true, + 'height' => 200, + 'yesButton' => $langs->trans('Ok'), + 'title' => $langs->transnoentities('GroupModeTransversalTitle'), + 'content' => img_warning().' '.$langs->trans('GroupModeTransversalInfo') + ) + ) +); +print ajax_mcconstantonoff('MULTICOMPANY_TRANSVERSE_MODE', $input, 0); +print '
'.$langs->trans("EnableGlobalSharings").' '; + $input = array( + 'alert' => array( + 'set' => array( + 'info' => true, + 'yesButton' => $langs->trans('Ok'), + 'title' => $langs->transnoentities('GlobalSharings'), + 'content' => img_warning().' '.$langs->trans('GlobalSharingsInfo') + ) + ), + 'showhide' => array( + '#shareelementtitle', + '#sharethirdparty' + ), + 'hide' => array( + '#shareelementtitle', + '#shareobjecttitle', + '#sharethirdparty' + ), + 'del' => array( + 'MULTICOMPANY_THIRDPARTY_SHARING_ENABLED' + ) + ); + foreach ($object->sharingelements as $key => $values) + { + if (! isset($values['disable'])) { + if (isset($values['input']) && isset($values['input']['global'])) { + if (isset($values['input']['global']['showhide']) && $values['input']['global']['showhide'] === true) { + if (! isset($input['showhide'])) $input['showhide'] = array(); + array_push($input['showhide'], '#share'.$key); + } + if (isset($values['input']['global']['hide']) && $values['input']['global']['hide'] === true) { + if (! isset($input['hide'])) $input['hide'] = array(); + array_push($input['hide'], '#share'.$key); + } + if (isset($values['input']['global']['del']) && $values['input']['global']['del'] === true) { + if (! isset($input['del'])) $input['del'] = array(); + array_push($input['del'], 'MULTICOMPANY_'.strtoupper($key).'_SHARING_ENABLED'); + } + } + } + } + print ajax_mcconstantonoff('MULTICOMPANY_SHARINGS_ENABLED', $input, 0); + print '
'.$langs->trans("ActivatingShares").' '.$form->textwithtooltip('',$htmltext,2,1,$text).' '.$langs->trans("Value").'
'.$langs->trans("ShareThirdpartiesAndContacts").' '; + $input = array( + 'showhide' => array( + '#shareobjecttitle' + ) + ); + foreach ($object->sharingelements as $key => $values) + { + if (! isset($values['disable']) && ($values['type'] === 'object' || $values['type'] === 'objectnumber')) + { + if (isset($values['input']) && isset($values['input']['thirdparty'])) { + if (isset($values['input']['thirdparty']['showhide']) && $values['input']['thirdparty']['showhide'] === true) { + if (! isset($input['showhide'])) $input['showhide'] = array(); + array_push($input['showhide'], '#share'.$key); + } + if (isset($values['input']['thirdparty']['hide']) && $values['input']['thirdparty']['hide'] === true) { + if (! isset($input['hide'])) $input['hide'] = array(); + array_push($input['hide'], '#share'.$key); + } + if (isset($values['input']['thirdparty']['del']) && $values['input']['thirdparty']['del'] === true) { + if (! isset($input['del'])) $input['del'] = array(); + array_push($input['del'], 'MULTICOMPANY_'.strtoupper($key).'_SHARING_ENABLED'); + } + } + } + } + print ajax_mcconstantonoff('MULTICOMPANY_THIRDPARTY_SHARING_ENABLED', $input, 0); + print '
'; + print ''.$langs->trans("Share".ucfirst($element)).(! empty($tooltip) ? ' '.$tooltip : '').' '; + + $input = array(); + foreach ($object->sharingelements as $key => $values) { + if (! isset($values['disable']) && isset($values['input']) && isset($values['input'][$element])) { + if (isset($values['input'][$element]['showhide']) && $values['input'][$element]['showhide'] === true) { + if (! isset($input['showhide'])) $input['showhide'] = array(); + array_push($input['showhide'], '#share'.$key); + } + if (isset($values['input'][$element]['hide']) && $values['input'][$element]['hide'] === true) { + if (! isset($input['hide'])) $input['hide'] = array(); + array_push($input['hide'], '#share'.$key); + } + if (isset($values['input'][$element]['del']) && $values['input'][$element]['del'] === true) { + if (! isset($input['del'])) $input['del'] = array(); + array_push($input['del'], 'MULTICOMPANY_'.strtoupper($key).'_SHARING_ENABLED'); + } + } + } + + print ajax_mcconstantonoff('MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED', $input, 0); + print '
'.$langs->trans("ActivatingObjectShares").' '.$form->textwithtooltip('', $htmltext, 2, 1, $text).' '.$langs->trans("Value").'
'; + print ''.$langs->trans("Share".ucfirst($element)).(! empty($tooltip) ? ' '.$tooltip : '').' '; + $input = array(); + print ajax_mcconstantonoff('MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED', $input, 0); + print '
'.$langs->trans("ActivatingDictsShares").' '.$form->textwithtooltip('',$htmltext,2,1,$text).' '.$langs->trans("Value").'
'.$langs->trans("Share".ucfirst($dict)).' '; + print ajax_mcconstantonoff('MULTICOMPANY_'.strtoupper($dict).'_SHARING_DISABLED', '', 0); + print '
'; + +// Card end +dol_fiche_end(); +// Footer +llxFooter(); +// Close database handler +$db->close(); diff --git a/htdocs/custom/multicompany/admin/tpl/caches.tpl.php b/htdocs/custom/multicompany/admin/tpl/caches.tpl.php new file mode 100755 index 00000000000..8e4357cd6f7 --- /dev/null +++ b/htdocs/custom/multicompany/admin/tpl/caches.tpl.php @@ -0,0 +1,118 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +global $form; +?> + + +
+
"> +
trans("MulticompanySession"); ?>
trans('MulticompanySessionDescription'); ?>

+
+
+
+
+ array('MULTICOMPANY_MEMCACHED_ENABLED','MULTICOMPANY_SHMOP_ENABLED'), + 'disabled' => array('MULTICOMPANY_MEMCACHED_SERVER') + ); + echo ajax_mcconstantonoff('MULTICOMPANY_SESSION_ENABLED', $input, 0); + ?> +
+
+
+ +
+
"> +
trans("MulticompanyMemcached"); ?>
trans('MulticompanyMemcachedDescription'); ?>

+
+
+ global->MULTICOMPANY_MEMCACHED_SERVER)?$conf->global->MULTICOMPANY_MEMCACHED_SERVER:(!empty($conf->global->MEMCACHED_SERVER)?$conf->global->MEMCACHED_SERVER:'127.0.0.1:11211')); + + $tmparray=explode(':',$serveraddress); + $server=$tmparray[0]; + $port=$tmparray[1]?$tmparray[1]:11211; + + $result=$m->addServer($server, $port); + $arraycache=$m->getStats(); + + if (is_array($arraycache)) + echo $form->textwithtooltip('',$langs->trans("MemcachedServerIsReady"),2,1,img_picto('','tick'),'',3); + else + echo $form->textwithtooltip('',$langs->trans("MemcachedServerIsNotReady"),2,1,img_warning(''),'',3); + + echo ' global->MULTICOMPANY_MEMCACHED_ENABLED) ? ' disabled="disabled"' : '').' />'; + } + else + echo img_warning($langs->trans("MulticompanyMemcachedUnavailable")).' '.$langs->trans("MulticompanyMemcachedUnavailable"); + ?> +
+
+
+ array('MULTICOMPANY_SHMOP_ENABLED','MULTICOMPANY_SESSION_ENABLED'), + 'disabledenabled' => array('MULTICOMPANY_MEMCACHED_SERVER') + ); + echo ajax_mcconstantonoff('MULTICOMPANY_MEMCACHED_ENABLED', $input, 0); + } + else + echo ''.img_picto($langs->trans("Disabled"),'switch_off', 'class="button-not-allowed"').''; + ?> +
+
+
+ +
+
"> +
trans("MulticompanyShmop"); ?>
trans('MulticompanyShmopDescription'); ?>

+
+
+ trans("MulticompanyShmopAvailable"),'tick').' '.$langs->trans("MulticompanyShmopAvailable"); + else + echo img_warning($langs->trans("MulticompanyShmopUnavailable")).' '.$langs->trans("MulticompanyShmopUnavailable"); + ?> +
+
+
+ array('MULTICOMPANY_MEMCACHED_ENABLED','MULTICOMPANY_SESSION_ENABLED'), + 'disabled' => array('MULTICOMPANY_MEMCACHED_SERVER') + ); + echo ajax_mcconstantonoff('MULTICOMPANY_SHMOP_ENABLED', $input, 0); + } + else + echo ''.img_picto($langs->trans("Disabled"),'switch_off', 'class="button-not-allowed"').''; + ?> +
+
+
+ \ No newline at end of file diff --git a/htdocs/custom/multicompany/admin/tpl/card.tpl.php b/htdocs/custom/multicompany/admin/tpl/card.tpl.php new file mode 100755 index 00000000000..b41ff737d7c --- /dev/null +++ b/htdocs/custom/multicompany/admin/tpl/card.tpl.php @@ -0,0 +1,386 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +?> + + + +
" method="POST"> + + +tpl['action'] === 'create') { ?> + + + + + + + + + + + + + + + + + + + +global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { + if ($this->tpl['action'] === 'create') { ?> + + + + + + + + +tpl['template'] === 1) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +tpl['extrafields']->attribute_label)) { + print $this->dao->showOptionals($this->tpl['extrafields'], 'edit'); +} +if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) { + +foreach($this->sharingelements as $element => $params) { + if ($params['type'] === 'element' && ! empty($this->tpl['multiselect_from_' . $element])) { + $uppername = strtoupper($element); + $icon = (! empty($params['icon'])?$params['icon']:'edit'); +?> + + + + + + + +global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { ?> + + + + + + + + + +sharingelements as $element => $params) { + if ($params['type'] !== 'element' && ! empty($this->tpl['multiselect_from_' . $element])) { + $uppername = strtoupper($element); + $icon = (! empty($params['icon'])?$params['icon']:'edit'); +?> + + + + + + + + +global->MULTICOMPANY_PROPOSALNUMBER_SHARING_ENABLED)) { ?> + + + + + + + +global->MULTICOMPANY_INVOICENUMBER_SHARING_ENABLED)) { ?> + + + + + + + +global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { ?> + + + + + + + + + +
trans("CompanyInfo"); ?>trans("Value"); ?>
trans("Label"); ?>
trans("CompanyName"); ?>
trans("TemplateOfCompany"); ?>tpl['template']; ?>
trans("SelectTemplateOfCompany"); ?>tpl['select_template']; ?>
trans("WarningThisIsATemplate"); ?>
trans("CompanyAddress"); ?>
trans("CompanyZip"); ?>tpl['select_zip']; ?>
trans("CompanyTown"); ?>tpl['select_town']; ?>
trans("Country"); ?>tpl['select_country'].$this->tpl['info_admin']; ?>
trans("State"); ?>tpl['select_state']; ?>
trans("CompanyCurrency"); ?>tpl['select_currency']; ?>
trans("DefaultLanguage"); ?>tpl['select_language']; ?>
trans("Description"); ?>
trans($uppername . "Sharing"); ?>
trans($uppername . "SharingDescription"); ?> +
+
+
trans("EntitiesSelected"); ?>
+ tpl['multiselect_to_' . $element]; ?> +
+
+ + + + + + +
+
+
trans("EntitiesAvailable"); ?>
+ tpl['multiselect_from_' . $element]; ?> +
+
+
trans("AddNewEntityInAllOtherEntities"); ?>tpl['addtoallother_' . $element]; ?>
 
trans($uppername . "Sharing"); ?>
trans($uppername . "SharingDescription"); ?> +
+
+
trans("EntitiesSelected"); ?>
+ tpl['multiselect_to_' . $element]; ?> +
+
+ + + + + + +
+
+
trans("EntitiesAvailable"); ?>
+ tpl['multiselect_from_' . $element]; ?> +
+
+
trans("ReferringEntityForProposalNumber"); ?>tpl['select_proposalnumber_entity']; ?>
 
trans("ReferringEntityForInvoiceNumber"); ?>tpl['select_invoicenumber_entity']; ?>
 
trans("AddNewEntityInAllOtherEntities"); ?>tpl['addtoallother_' . $element]; ?>
 
+ + +
+tpl['action'] === 'create') { ?> + +" /> + + + +" /> + +" /> +
+ +
+ + diff --git a/htdocs/custom/multicompany/admin/tpl/index.html b/htdocs/custom/multicompany/admin/tpl/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/admin/tpl/list.tpl.php b/htdocs/custom/multicompany/admin/tpl/list.tpl.php new file mode 100755 index 00000000000..81d297f88bc --- /dev/null +++ b/htdocs/custom/multicompany/admin/tpl/list.tpl.php @@ -0,0 +1,230 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +dol_include_once('/multicompany/admin/tpl/switch.tpl.php'); + +$colHidden = (! empty($conf->global->MULTICOMPANY_COLHIDDEN) ? implode(",", json_decode($conf->global->MULTICOMPANY_COLHIDDEN, true)) : null); +$colOrder = (! empty($conf->global->MULTICOMPANY_COLORDER) ? json_decode($conf->global->MULTICOMPANY_COLORDER, true) : array('id' => 0, 'direction' => 'asc')); + +$columns = array(); + +$columns['id'] = array( + 'label' => 'ID', + 'sortable' => true, + 'searchable' => true, + 'priority' => 12, + 'center' => 'dt-center' +); +$columns['label'] = array( + 'label' => 'Label', + 'sortable' => true, + 'searchable' => true, + 'priority' => 1, +); +$columns['description'] = array( + 'label' => 'Description', + 'sortable' => true, + 'searchable' => true, + 'priority' => 11, +); +$columns['name'] = array( + 'label' => 'Name', + 'priority' => 10, + 'center' => 'dt-center' +); +$columns['zip'] = array( + 'label' => 'Zip', + 'priority' => 9, + 'center' => 'dt-center' +); +$columns['town'] = array( + 'label' => 'Town', + 'priority' => 8, + 'center' => 'dt-center' +); +$columns['country'] = array( + 'label' => 'Country', + 'priority' => 7, + 'center' => 'dt-center' +); +$columns['currency'] = array( + 'label' => 'Currency', + 'priority' => 6, + 'center' => 'dt-center' +); +$columns['language'] = array( + 'label' => 'DefaultLanguageShort', + 'priority' => 5, + 'center' => 'dt-center' +); +if (! empty($this->tpl['extrafields']->attribute_label)) { + foreach ($this->tpl['extrafields']->attribute_label as $key => $value) + { + $columns[$key] = array( + 'label' => $value, + 'center' => 'dt-center' + ); + } +} +$columns['visible'] = array( + 'label' => 'Visible', + 'width' => '20px', + 'priority' => 3, + 'center' => 'dt-center' +); +$columns['active'] = array( + 'label' => 'Status', + 'width' => '20px', + 'priority' => 2, + 'center' => 'dt-center' +); +$columns['tools'] = array( + 'label' => 'Tools', + 'width' => '50px', + 'priority' => 4, + 'center' => 'dt-center' +); + +//var_dump($columns); + +?> + + + + + + + $values) { + //$moreattr = (! empty($values['priority'])?'data-priority="'.$values['priority'].'"':''); + echo getTitleFieldOfList($values['label'], 1, '', '', '', '', $moreattr, '', '', 'entity_' . $key . ' '); + } + ?> + + + + + + + +
trans('LoadingDataFromServer'); ?>
+ + \ No newline at end of file diff --git a/htdocs/custom/multicompany/admin/tpl/switch.tpl.php b/htdocs/custom/multicompany/admin/tpl/switch.tpl.php new file mode 100755 index 00000000000..4261a0ef6c2 --- /dev/null +++ b/htdocs/custom/multicompany/admin/tpl/switch.tpl.php @@ -0,0 +1,122 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +?> + + +
+

trans('ConfirmDeleteEntity'); ?>

+
+ + \ No newline at end of file diff --git a/htdocs/custom/multicompany/class/actions_multicompany.class.php b/htdocs/custom/multicompany/class/actions_multicompany.class.php new file mode 100755 index 00000000000..f73d69db5bd --- /dev/null +++ b/htdocs/custom/multicompany/class/actions_multicompany.class.php @@ -0,0 +1,4608 @@ + + * Copyright (C) 2011 Herve Prot + * Copyright (C) 2014 Philippe Grand + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/multicompany/actions_multicompany.class.php + * \ingroup multicompany + * \brief File Class multicompany + */ + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany'); +dol_include_once('/multicompany/lib/multicompany.lib.php'); + +/** + * Class Actions of the module multicompany + */ +class ActionsMulticompany +{ + /** @var DoliDB */ + var $db; + /** @var DaoMulticompany */ + var $dao; + + var $mesg; + var $error; + var $errors=array(); + //! Numero de l'erreur + var $errno = 0; + + var $template_dir; + var $template; + + var $label; + var $description; + + var $referent; + + var $sharings=array(); + var $options=array(); + var $entities=array(); + var $dict=array(); + var $tpl=array(); + + var $addzero=array(); + var $sharingelements=array(); + var $sharingobjects=array(); + var $sharingdicts=array(); + + private $config=array(); + + // For Hookmanager return + var $resprints; + var $results=array(); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf; + + $this->db = $db; + + $this->addzero = array( + 'user', + 'usergroup', + 'c_email_templates', + 'email_template', + 'default_values' + ); + + // Default sharing elements + $this->sharingelements = array( + 'thirdparty' => array( + 'type' => 'element', + 'icon' => 'building', + 'active' => true, // for setEntity() function + 'disable' => true // disable in options tab + ), + 'member' => array( + 'type' => 'element', + 'icon' => 'address-card', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'member_type' => array( + 'type' => 'element', + 'icon' => 'address-card', + 'display' => '! empty($conf->global->MULTICOMPANY_MEMBER_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'member' => array( + 'showhide' => true, + 'del' => true + ) + ) + ), + 'product' => array( + 'type' => 'element', + 'icon' => 'cube', + 'tooltip' => 'ProductSharingInfo', + 'enable' => '(! empty($conf->product->enabled) || ! empty($conf->service->enabled))', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ), + 'active' => true + ), + 'productprice' => array( + 'type' => 'element', + 'icon' => 'money', + 'tooltip' => 'ProductPriceSharingInfo', + 'enable' => '(! empty($conf->product->enabled) || ! empty($conf->service->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'product' => array( + 'showhide' => true, + 'del' => true + ) + ) + ), + 'productsupplierprice' => array( + 'type' => 'element', + 'icon' => 'money', + 'enable' => '((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && ! empty($conf->fournisseur->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'product' => array( + 'showhide' => true, + 'del' => true + ) + ), + ), + 'stock' => array( + 'type' => 'element', + 'icon' => 'cubes', + //'tooltip' => 'SharingStockInfo', + 'enable' => '(! empty($conf->stock->enabled) && (! empty($conf->product->enabled) || ! empty($conf->service->enabled)))', + 'display' => '! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'product' => array( + 'showhide' => true, + 'del' => true + ) + ) + ), + 'category' => array( + 'type' => 'element', + 'icon' => 'paperclip', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'agenda' => array( + 'type' => 'element', + 'icon' => 'calendar', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'bankaccount' => array( + 'type' => 'element', + 'icon' => 'bank', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'expensereport' => array( + 'type' => 'element', + 'icon' => 'edit', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'holiday' => array( + 'type' => 'element', + 'icon' => 'paper-plane-o', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'project' => array( + 'type' => 'element', + 'icon' => 'code-fork', + 'input' => array( + 'global' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + + // Object + + 'proposal' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', + 'mandatory' => 'thirdparty', + 'enable' => '(! empty($conf->propal->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ), + 'active' => true + ), + 'proposalnumber' => array( + 'type' => 'objectnumber', + 'icon' => 'cogs', + 'mandatory' => 'thirdparty', + 'tooltip' => 'ProposalNumberSharingInfo', + 'enable' => '(! empty($conf->propal->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'order' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', // Font Awesome icon + 'mandatory' => 'thirdparty', + 'enable' => '(! empty($conf->commande->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ), + 'active' => true, + //'disable' => true // Disable if not stable + ), + 'ordernumber' => array( + 'type' => 'objectnumber', + 'icon' => 'cogs', + 'mandatory' => 'thirdparty', + 'tooltip' => 'OrderNumberSharingInfo', + 'enable' => '(! empty($conf->commande->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ), + //'disable' => true + ), + 'invoice' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', + 'mandatory' => 'thirdparty', + 'enable' => '(! empty($conf->facture->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ), + 'active' => true + ), + 'invoicenumber' => array( + 'type' => 'objectnumber', + 'icon' => 'cogs', + 'mandatory' => 'thirdparty', + 'tooltip' => 'InvoiceNumberSharingInfo', + 'enable' => '(! empty($conf->facture->enabled) && ! empty($conf->societe->enabled))', + 'display' => '! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ), + 'thirdparty' => array( + 'showhide' => true, + 'hide' => true, + 'del' => true + ) + ) + ), + 'supplier_proposal' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ) + ), + 'disable' => true + ), + 'supplier_order' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ) + ), + 'disable' => true + ), + 'supplier_invoice' => array( + 'type' => 'object', + 'icon' => 'file-pdf-o', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ) + ), + 'disable' => true + ), + 'intervention' => array( + 'type' => 'object', + 'icon' => 'wrench', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true + ) + ), + 'disable' => true + ) + ); + + // Module name if different of object name (eg $conf->commande->enabled) + $this->sharingmodulename = array( + 'thirdparty' => 'societe', + 'proposal' => 'propal', + 'proposalnumber' => 'propal', + 'order' => 'commande', + 'ordernumber' => 'commande', + 'invoice' => 'facture', + 'invoicenumber' => 'facture', + 'product' => (empty($conf->product->enabled) && !empty($conf->service->enabled) ? 'service' : 'product'), + 'productprice' => 'product', + 'productsupplierprice' => 'product', + 'project' => 'projet', + 'member' => 'adherent', + 'membertype' => 'adherent', + 'member_type' => 'adherent', // deprecated + //'membertype' => 'member_type', // deprecated + 'intervention' => 'ficheinter', + 'category' => 'categorie', + 'bankaccount' => 'banque', + 'bank_account' => 'banque', // deprecated + //'bankaccount' => 'banque_account', // deprecated + ); + + $this->sharingdicts = array( + 'c_paiement' => array( + 'societe' => array( + 'mode_reglement', + 'mode_reglement_supplier' + ), + 'propal' => 'fk_mode_reglement', + 'commande' => 'fk_mode_reglement', + 'facture' => 'fk_mode_reglement', + 'facture_rec' => 'fk_mode_reglement', + 'commande_fournisseur' => 'fk_mode_reglement', + 'facture_fourn' => 'fk_mode_reglement', + 'supplier_proposal' => 'fk_mode_reglement', + 'chargesociales' => 'fk_mode_reglement', + 'don' => 'fk_payment', + 'paiement' => 'fk_paiement', + 'paiementfourn' => 'fk_paiement', + 'paiement_facture' => 'fk_paiement', + 'expensereport' => 'fk_c_paiement', + 'paiementcharge' => 'fk_typepaiement', + 'tva' => 'fk_typepayment', + 'payment_various' => 'fk_typepayment', + 'payment_salary' => 'fk_typepayment', + 'payment_expensereport' => 'fk_typepayment', + 'payment_donation' => 'fk_typepayment', + 'loan_schedule' => 'fk_typepayment', + 'payment_loan' => 'fk_typepayment' + ), + 'c_payment_term' => array( + 'societe' => array( + 'cond_reglement', + 'cond_reglement_supplier' + ), + 'propal' => 'fk_cond_reglement', + 'commande' => 'fk_cond_reglement', + 'facture' => 'fk_cond_reglement', + 'facture_rec' => 'fk_cond_reglement', + 'commande_fournisseur' => 'fk_cond_reglement', + 'facture_fourn' => 'fk_cond_reglement', + 'supplier_proposal' => 'fk_cond_reglement' + ) + ); + + if (! empty($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING)) + { + $externalmodules = json_decode($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING, true); + + if (is_array($externalmodules) && ! empty($externalmodules)) + { + foreach($externalmodules as $params) + { + if (is_array($params) && ! empty($params)) + { + if (is_array($params['addzero']) && ! empty($params['addzero'])) { + array_push($this->addzero, $params['addzero']); + } + + if (is_array($params['sharingelements']) && ! empty($params['sharingelements'])) { + $this->sharingelements = array_merge($this->sharingelements, $params['sharingelements']); + } + + if (is_array($params['sharingmodulename']) && ! empty($params['sharingmodulename'])) + { + $this->sharingmodulename = array_merge($this->sharingmodulename, $params['sharingmodulename']); + } + } + } + } + } + } + + /** + * Instantiation of DAO class + * + * @return void + */ + private function getInstanceDao() + { + if (! is_object($this->dao)) + { + $this->dao = new DaoMulticompany($this->db); + } + } + + + /** + * setHtmlTitle + * + * @param array $parameters Hook metadatas (context, etc...) + */ + public function setHtmlTitle($parameters=false) + { + global $conf; + + if (empty($conf->global->MULTICOMPANY_HIDE_HTML_TITLE)) { + $this->resprints = ' + multicompany'; + } + + return 0; + } + + + /** + * Enter description here ... + * + * @param string $action Action type + */ + public function doAdminActions(&$action='') + { + global $conf, $user, $langs; + + $this->getInstanceDao(); + + $id = GETPOST('id','int'); + $label = GETPOST('label','alpha'); + $name = GETPOST('name','alpha'); + $description = GETPOST('description','alpha'); + $cancel = GETPOST('cancel', 'alpha'); + $addandstay = GETPOST('addandstay', 'alpha'); + $cancelandstay = GETPOST('cancelandstay', 'alpha'); + $updateandstay = GETPOST('updateandstay', 'alpha'); + $template = (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) ? null : GETPOST('template', 'int')); + $usetemplate = (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) ? null : GETPOST('usetemplate', 'int')); + $visible = GETPOST('visible', 'int'); + $active = GETPOST('active', 'int'); + + if ($action === 'add' && empty($cancel) && $user->admin && ! $user->entity) + { + $error=0; + + if (empty($label)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), 'errors'); + $action = 'create'; + } + else if (empty($name)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CompanyName")), 'errors'); + $action = 'create'; + } + + // Verify if label already exist in database + if (! $error) + { + $this->dao->getEntities(); + if (! empty($this->dao->entities)) + { + foreach($this->dao->entities as $entity) + { + if (strtolower($entity->label) == strtolower($label)) $error++; + } + if ($error) + { + setEventMessage($langs->trans("ErrorEntityLabelAlreadyExist"), 'errors'); + $action = 'create'; + } + } + } + + if (! $error) + { + $this->db->begin(); + + $this->dao->label = $label; + $this->dao->description = $description; + $this->dao->visible = ((! empty($template) && empty($usetemplate)) ? 2 : ((! empty($visible) || ! empty($conf->global->MULTICOMPANY_VISIBLE_BY_DEFAULT)) ? 1 : 0)); + $this->dao->active = ((! empty($active) || ! empty($conf->global->MULTICOMPANY_ACTIVE_BY_DEFAULT))?1:0); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) { + $this->dao->options['proposalnumber_referent'] = (GETPOST('proposalnumber_referring_entity', 'int') ? GETPOST('proposalnumber_referring_entity', 'int') : null); + $this->dao->options['invoicenumber_referent'] = (GETPOST('invoicenumber_referring_entity', 'int') ? GETPOST('invoicenumber_referring_entity', 'int') : null); + foreach ($this->sharingelements as $element => $params) { + if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue; + $uppername = strtoupper($element); + $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED'; + if (! empty($conf->global->$constname)) { + $shareentities = GETPOST($element.'_to', 'array'); + $shareentities = array_unique($shareentities); sort($shareentities); + $this->dao->options['sharings'][$element] = (! empty($shareentities) ? $shareentities : null); + if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { + $this->dao->options['addtoallother'][$element] = GETPOST('addtoallother_'.$element, 'int'); + } + } + } + } + + $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($this->dao->table_element, true); + $extrafields->setOptionalsFromPost($extralabels, $this->dao); + + $id = $this->dao->create($user); + if ($id <= 0) + { + $error++; + $errors=($this->dao->error ? array($this->dao->error) : $this->dao->errors); + setEventMessage($errors, 'errors'); + $action = 'create'; + } + + if (! $error && $id > 0) + { + if (! empty($usetemplate) && is_numeric($usetemplate)) + { + $const = $this->dao->getEntityConfig($usetemplate); + if (! empty($const)) + { + // Reload modules + foreach ($const as $key => $value) + { + if (preg_match('/^MAIN\_MODULE\_([0-9A-Z]+)$/', $key, $reg)) + { + if (! empty($reg[1])) + { + $classname = 'mod' . ucfirst(strtolower($reg[1])); + + $res = @include_once DOL_DOCUMENT_ROOT.'/core/modules/'.$classname.'.class.php'; + + if ($res) { + dol_syslog(get_class($this)."::reloadModules template=".$usetemplate." module=".$key." classname=".$classname, LOG_DEBUG); + $mod=new $classname($this->db); + $mod->init('forceactivate'); + } else { + dol_syslog(get_class($this)."::reloadModules template=".$usetemplate." module=".$key." classname=".$classname, LOG_ERR); + } + } + } + } + + // Overwrite with template + foreach ($const as $key => $value) + { + dolibarr_set_const($this->db, $key, $value, 'chaine', 0, '', $id); + } + } + } + + $country_id = GETPOST('country_id', 'int'); + $country = getCountry($country_id, 'all'); + $country_code = $country['code']; + $country_label = $country['label']; + + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_COUNTRY", $country_id.':'.$country_code.':'.$country_label,'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_NOM",$name,'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ADDRESS",GETPOST('address', 'alpha'),'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_TOWN",GETPOST('town', 'alpha'),'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ZIP",GETPOST('zipcode', 'alpha'),'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_STATE",GETPOST('departement_id', 'int'),'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_MONNAIE",GETPOST('currency_code', 'alpha'),'chaine',0,'',$id); + dolibarr_set_const($this->db, "MAIN_LANG_DEFAULT",GETPOST('main_lang_default', 'alpha'),'chaine',0,'',$id); + + if (empty($usetemplate)) + { + $dir = "/multicompany/sql/"; + + // Load sql init_new_entity.sql file + $file = 'init_new_entity_nocrypt.sql'; + if (! empty($conf->db->dolibarr_main_db_encryption) && ! empty($conf->db->dolibarr_main_db_cryptkey)) + { + $file = 'init_new_entity.sql'; + } + $fullpath = dol_buildpath($dir.$file); + + if (file_exists($fullpath)) + { + $result=run_sql($fullpath,1,$id); + } + + $dir = "/multicompany/sql/dict/"; + + foreach($this->sharingdicts as $dict => $data) + { + // Load sql init_new_entity_dict.sql file + $file = 'init_new_entity_'.$dict.'.sql'; + $fullpath = dol_buildpath($dir.$file); + + if (file_exists($fullpath)) + { + $result = run_sql($fullpath, 1, $id); + } + } + } + else + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + $modulesdir = dolGetModulesDirs(); + + foreach ($modulesdir as $dir) + { + // Load modules attributes in arrays (name, numero, orders) from dir directory + //print $dir."\n
"; + $handle=@opendir(dol_osencode($dir)); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') + { + $modName = substr($file, 0, dol_strlen($file) - 10); + + if ($modName) + { + include_once $dir."/".$file; + $objMod = new $modName($this->db); + // Load all lang files of module + if (isset($objMod->langfiles) && is_array($objMod->langfiles)) + { + foreach($objMod->langfiles as $domain) + { + $langs->load($domain); + } + } + // Load all permissions + if ($objMod->rights_class) + { + $ret=$objMod->insert_permissions(0, $id); + } + } + } + } + } + } + + // Add entity to all others entities + if (! empty($this->dao->options['addtoallother'])) + { + $this->dao->getEntities(true, array($id), false); + foreach ($this->dao->entities as $entity) + { + if (! is_array($entity->options)) $entity->options = array(); + if (! is_array($entity->options['sharings'])) $entity->options['sharings'] = array(); + + foreach($this->dao->options['sharings'] as $element => $values) + { + if (! is_array($entity->options['sharings'][$element])) $entity->options['sharings'][$element] = array(); + + if ($this->dao->options['addtoallother'][$element] == '1') + { + array_push($entity->options['sharings'][$element], (string) $id); + $entity->update($entity->id, $user); + } + } + } + } + + $listofgroups = $this->dao->getListOfGroups(); + if (! empty($listofgroups)) + { + foreach($listofgroups as $groupid) + { + // Duplicate usergroup rights + $ret = $this->duplicateUserGroupRights($groupid, $usetemplate, array($id)); + if ($ret < 0) $error++; + + // Add users to groups if linked with template + $userslist = $this->dao->getListOfUsersInGroupByTemplate($groupid, $usetemplate); + if ($userslist < 0) $error++; + elseif (! empty($userslist)) + { + foreach($userslist as $usertemplate) + { + $result = $usertemplate->SetInGroup($groupid, $id); + if ($result < 0) + { + $error++; + break; + } + } + } + } + } + } + + if (! $error) + { + $this->db->commit(); + } + else + { + $this->db->rollback(); + } + + if (! empty($addandstay)) + { + header("Location: " . $_SERVER['PHP_SELF'].'?action=edit&id='.$id); + exit; + } + } + else + { + $this->db->rollback(); + } + } + } + else if ($action === 'edit' && $user->admin && ! $user->entity) + { + $error=0; + + if (! empty($cancel)) + { + header("Location: " . $_SERVER['PHP_SELF']); + exit; + } + + if ($this->dao->fetch($id) < 0) + { + $error++; + setEventMessage($langs->trans("ErrorEntityIsNotValid"), 'errors'); + $action = ''; + } + } + else if ($action === 'update' && empty($cancel) && $id > 0 && $user->admin && ! $user->entity) + { + $error=0; + + if (! empty($cancelandstay)) + { + $action = 'edit'; + return; + } + + $ret = $this->dao->fetch($id); + if ($ret < 0) + { + $error++; + setEventMessage($langs->trans("ErrorEntityIsNotValid"), 'errors'); + $action = ''; + } + else if (empty($label)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), 'errors'); + $action = 'edit'; + } + else if (empty($name)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("CompanyName")), 'errors'); + $action = 'edit'; + } + + // Verify if label already exist in database + if (! $error) + { + $this->dao->getEntities(); + if (! empty($this->dao->entities)) + { + foreach($this->dao->entities as $entity) + { + if ($entity->id == $this->dao->id) continue; + if (strtolower($entity->label) == strtolower($label)) $error++; + } + if ($error) + { + setEventMessage($langs->trans("ErrorEntityLabelAlreadyExist"), 'errors'); + $action = 'edit'; + } + } + } + + if (! $error) + { + $this->db->begin(); + + $this->dao->label = $label; + $this->dao->description = $description; + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) { + $this->dao->options['proposalnumber_referent'] = (GETPOST('proposalnumber_referring_entity', 'int') ? GETPOST('proposalnumber_referring_entity', 'int') : null); + $this->dao->options['invoicenumber_referent'] = (GETPOST('invoicenumber_referring_entity', 'int') ? GETPOST('invoicenumber_referring_entity', 'int') : null); + foreach ($this->sharingelements as $element => $params) { + if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue; + $uppername = strtoupper($element); + $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED'; + if (! empty($conf->global->$constname)) { + $shareentities = GETPOST($element.'_to', 'array'); + $shareentities = array_unique($shareentities); sort($shareentities); + $this->dao->options['sharings'][$element] = (! empty($shareentities) ? $shareentities : null); + if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { + $this->dao->options['addtoallother'][$element] = GETPOST('addtoallother_'.$element, 'int'); + } + } + } + } + + $extrafields = new ExtraFields($this->db); + $extralabels = $extrafields->fetch_name_optionals_label($this->dao->table_element, true); + $extrafields->setOptionalsFromPost($extralabels, $this->dao); + + $ret = $this->dao->update($this->dao->id, $user); + if ($ret <= 0) + { + $error++; + $errors=($this->dao->error ? array($this->dao->error) : $this->dao->errors); + setEventMessage($errors, 'errors'); + $action = 'edit'; + } + + if (! $error && $ret > 0) + { + $country_id = GETPOST('country_id', 'int'); + $country = getCountry($country_id, 'all'); + $country_code = $country['code']; + $country_label = $country['label']; + + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_COUNTRY", $country_id.':'.$country_code.':'.$country_label,'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_NOM",$name,'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ADDRESS",GETPOST('address', 'alpha'),'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_TOWN",GETPOST('town', 'alpha'),'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_ZIP",GETPOST('zipcode', 'alpha'),'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_INFO_SOCIETE_STATE",GETPOST('departement_id', 'int'),'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_MONNAIE",GETPOST('currency_code', 'alpha'),'chaine',0,'',$this->dao->id); + dolibarr_set_const($this->db, "MAIN_LANG_DEFAULT",GETPOST('main_lang_default', 'alpha'),'chaine',0,'',$this->dao->id); + + $this->db->commit(); + + if (! empty($updateandstay)) { + $action = 'edit'; + } + } + else + { + $this->db->rollback(); + } + } + } + } + + /** + * Return action of hook + * @param object Linked object + */ + public function doActions($parameters=false, &$object, &$action='') + { + global $conf, $user; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + // Clear constants cache after company infos update + if (is_array($currentcontext)) + { + if ((in_array('admincompany', $currentcontext) || in_array('adminihm', $currentcontext)) && ($action == 'update' || $action == 'updateedit')) + { + clearCache($conf->entity); + clearCache('constants_' . $conf->entity); + } + else if ((in_array('groupcard', $currentcontext) || in_array('groupperms', $currentcontext)) && $object->element == 'usergroup') + { + global $entity; + + // Users/Groups management only in master entity if transverse mode + if ($conf->entity > 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + accessforbidden(); + } + + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $entity=(GETPOST('entity','int') ? GETPOST('entity','int') : $conf->entity); + } else { + $entity=(! empty($object->entity) ? $object->entity : $conf->entity); + } + + // Add/Remove user into group + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && in_array('groupcard', $currentcontext) && ($action == 'adduser' || $action =='removeuser') && (! empty($userid) && $userid > 0) && $caneditperms) + { + if ($action == 'adduser') + { + $entities = GETPOST("entities", "array", 3); + + if (is_array($entities) && ! empty($entities)) + { + $error=0; + + foreach ($entities as $entity_id) + { + $object->fetch($id); + $object->oldcopy = clone $object; + + $edituser = new User($this->db); + $edituser->fetch($userid); + $result=$edituser->SetInGroup($object->id, $entity_id); + if ($result < 0) + { + $error++; + break; + } + } + if (!$error) + { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id); + exit; + } + else + { + $this->error = $edituser->error; + $this->errors = $edituser->errors; + return -1; + } + } + } + else if ($action == 'removeuser') + { + $object->fetch($id); + $object->oldcopy = clone $object; + + $edituser = new User($this->db); + $edituser->fetch($userid); + $result=$edituser->RemoveFromGroup($object->id, $entity); + + if ($result > 0) + { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit; + } + else + { + $this->error = $object->error; + $this->errors = $object->errors; + return -1; + } + } + return 1; + } + } + else if ((in_array('usercard', $currentcontext) || in_array('userperms', $currentcontext)) && $object->element == 'user') + { + global $entity, $caneditperms; + + // Users/Groups management only in master entity if transverse mode + if ($conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) + { + if (in_array('usercard', $currentcontext) && ($action == 'create' || $action == 'adduserldap')) { + accessforbidden(); + } else if (in_array('userperms', $currentcontext)) { + $caneditperms = false; + } + } + + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + if (GETPOSTISSET('entity')) { + + $entity = GETPOST('entity','int'); + + } else { + + $entity = $conf->entity; + + // Check usergroup if user not in master entity + if (in_array('userperms', $currentcontext) && ! empty($user->admin) && empty($user->entity) && $conf->entity == 1) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + $group = new UserGroup($this->db); + $ret = $group->listGroupsForUser($object->id, false); + if (! empty(current($ret)->usergroup_entity)) { + sort(current($ret)->usergroup_entity); + if (current($ret)->usergroup_entity[0] > 1) { + $entity = current($ret)->usergroup_entity[0]; + } + } + } + } + } else { + $entity=(! empty($object->entity) ? $object->entity : $conf->entity); + } + + // Action add usergroup + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && in_array('usercard', $currentcontext) && ($action == 'addgroup' || $action == 'removegroup') && (! empty($group) && $group > 0) && $caneditgroup) + { + if ($action == 'addgroup') + { + $entities = GETPOST("entities", "array", 3); + + if (is_array($entities) && ! empty($entities)) + { + $error=0; + + foreach ($entities as $entity_id) + { + $object->fetch($id); + $result = $object->SetInGroup($group, $entity_id); + if ($result < 0) + { + $error++; + break; + } + } + if ($error) + { + $this->error = $object->error; + $this->errors = $object->errors; + return -1; + } + else + { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id); + exit; + } + } + } + else if ($action == 'removegroup') + { + $object->fetch($id); + $result = $object->RemoveFromGroup($group, $entity); + if ($result > 0) { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id); + exit; + } + else + { + $this->error = $object->error; + $this->errors = $object->errors; + return -1; + } + } + return 1; + } + } + else if (in_array('productcard', $currentcontext) && ($object->element == 'product' || $object->element == 'service')) + { + if ($action != 'create' && $action != 'add') + { + if ($object->entity != $conf->entity) + { + global $usercanread, $usercancreate, $usercandelete; + + /*if (empty($user->rights->multicompany->product->read)) { + $usercanread = false; + }*/ + if (empty($user->rights->multicompany->product->write)) { + $usercancreate = false; + } + if (empty($user->rights->multicompany->product->delete)) { + $usercandelete = false; + } + } + } + } + else if (in_array('propalcard', $currentcontext) && $object->element == 'propal') + { + if ($action != 'create' && $action != 'add') + { + if ($object->entity != $conf->entity) + { + global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanclose; + global $permissionnote, $permissiondellink, $permissiontoedit; + global $disableedit, $disablemove, $disableremove; + + $this->getInstanceDao(); + + $constants = array( + 'PROPALE_ADDON', + 'PROPALE_SAPHIR_MASK', + 'PROPALE_ADDON_PDF', + 'PROPALE_ADDON_PDF_ODT_PATH' + ); + + if (empty($conf->global->MULTICOMPANY_PROPOSALNUMBER_SHARING_ENABLED) || empty($mc->sharings['proposalnumber'])) // Check if current entity not use the proposalnumber sharing + { + foreach ($constants as $constname) + { + $res = $this->dao->getEntityConfig($object->entity, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with object entity config + } + } + } + else + { + foreach ($constants as $constname) + { + $referent = (! empty($mc->proposalnumber_referent)?$mc->proposalnumber_referent:1); + $res = $this->dao->getEntityConfig($referent, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with referent config + } + } + } + + // Override $mysoc with data of object entity + if ($action == 'builddoc') + { + global $mysoc; + + $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*'); + if (! empty($current)) + { + foreach($current as $constname => $value) + { + unset($conf->global->$constname); + } + } + + $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*'); + if (! empty($other)) + { + foreach($other as $constname => $value) + { + $conf->global->$constname = $value; // override current entity config with referent config + } + } + + $mysoc->setMysoc($conf); + } + + if (empty($user->rights->multicompany->propal->read)) { + $usercanread = false; + } + if (empty($user->rights->multicompany->propal->write)) { + $usercancreate = false; + + $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php + $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php + + // for object lines + $disableedit = true; + $disablemove = true; + $disableremove = true; + } + if (empty($user->rights->multicompany->propal->delete)) { + $usercandelete = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->propal_advance->validate))) { + $usercanvalidate = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->propal_advance->send))) { + $usercansend = false; + } + if (empty($user->rights->multicompany->propal->close)) { + $usercanclose = false; + } + } + } + } + else if (in_array('ordercard', $currentcontext) && $object->element == 'commande') + { + if ($action != 'create' && $action != 'add') + { + if ($object->entity != $conf->entity) + { + global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanclose, $usercancancel; + global $permissionnote, $permissiondellink, $permissiontoedit; + global $disableedit, $disablemove, $disableremove; + + $this->getInstanceDao(); + + $constants = array( + 'COMMANDE_ADDON', + 'COMMANDE_SAPHIR_MASK', + 'COMMANDE_ADDON_PDF', + 'COMMANDE_ADDON_PDF_ODT_PATH' + ); + + if (empty($conf->global->MULTICOMPANY_ORDERNUMBER_SHARING_ENABLED) || empty($mc->sharings['ordernumber'])) // Check if current entity not use the proposalnumber sharing + { + foreach ($constants as $constname) + { + $res = $this->dao->getEntityConfig($object->entity, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with object entity config + } + } + } + else + { + foreach ($constants as $constname) + { + $referent = (! empty($mc->ordernumber_referent)?$mc->ordernumber_referent:1); + $res = $this->dao->getEntityConfig($referent, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with referent config + } + } + } + + // Override $mysoc with data of object entity + if ($action == 'builddoc') + { + global $mysoc; + + $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*'); + if (! empty($current)) + { + foreach($current as $constname => $value) + { + unset($conf->global->$constname); + } + } + + $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*'); + if (! empty($other)) + { + foreach($other as $constname => $value) + { + $conf->global->$constname = $value; // override current entity config with referent config + } + } + + $mysoc->setMysoc($conf); + } + + if (empty($user->rights->multicompany->order->read)) { + $usercanread = false; + } + if (empty($user->rights->multicompany->order->write)) { + $usercancreate = false; + + $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php + $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php + + // for object lines + $disableedit = true; + $disablemove = true; + $disableremove = true; + } + if (empty($user->rights->multicompany->order->delete)) { + $usercandelete = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->validate))) { + $usercanvalidate = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->cancel))) { + $usercancancel = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->order_advance->send))) { + $usercansend = false; + } + if (empty($user->rights->multicompany->order->close)) { + $usercanclose = false; + } + } + } + } + else if (in_array('invoicecard', $currentcontext) && $object->element == 'facture') + { + if ($action != 'create' && $action != 'add') + { + if ($object->entity != $conf->entity) + { + global $usercanread, $usercancreate, $usercandelete, $usercanvalidate, $usercansend, $usercanreopen, $usercanunvalidate; + global $permissionnote, $permissiondellink, $permissiontoedit; + global $disableedit, $disablemove, $disableremove; + + $this->getInstanceDao(); + + $constants = array( + 'FACTURE_ADDON', + 'FACTURE_MERCURE_MASK_INVOICE', + 'FACTURE_MERCURE_MASK_CREDIT', + 'FACTURE_MERCURE_MASK_DEPOSIT', + 'FACTURE_MERCURE_MASK_REPLACEMENT', + 'PROPALE_ADDON_PDF', + 'FACTURE_ADDON_PDF_ODT_PATH' + ); + + if (empty($conf->global->MULTICOMPANY_INVOICENUMBER_SHARING_ENABLED) || empty($mc->sharings['invoicenumber'])) // Check if current entity not use the proposalnumber sharing + { + foreach ($constants as $constname) + { + $res = $this->dao->getEntityConfig($object->entity, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with object entity config + } + } + } + else + { + foreach ($constants as $constname) + { + $referent = (! empty($mc->invoicenumber_referent)?$mc->invoicenumber_referent:1); + $res = $this->dao->getEntityConfig($referent, $constname); + if (! empty($res[$constname])) { + $conf->global->$constname = $res[$constname]; // override current entity config with referent config + } + } + } + + // Override $mysoc with data of object entity + if ($action == 'builddoc') + { + global $mysoc; + + $current = $this->dao->getEntityConfig($conf->entity, 'MAIN_INFO_*'); + if (! empty($current)) + { + foreach($current as $constname => $value) + { + unset($conf->global->$constname); + } + } + + $other = $this->dao->getEntityConfig($object->entity, 'MAIN_INFO_*'); + if (! empty($other)) + { + foreach($other as $constname => $value) + { + $conf->global->$constname = $value; // override current entity config with referent config + } + } + + $mysoc->setMysoc($conf); + } + + if (empty($user->rights->multicompany->invoice->read)) { + $usercanread = false; + } + if (empty($user->rights->multicompany->invoice->write)) { + $usercancreate = false; + + $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php + $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php + + // for object lines + $disableedit = true; + $disablemove = true; + $disableremove = true; + } + if (empty($user->rights->multicompany->invoice->delete)) { + $usercandelete = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->validate))) { + $usercanvalidate = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercanread)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->send))) { + $usercansend = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->multicompany->invoice_advance->reopen))) { + $usercanreopen = false; + } + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->multicompany->invoice_advance->unvalidate))) { + $usercanunvalidate = false; + } + } + } + } + } + + //var_dump($_POST); +/* + if (empty($_SESSION['dol_tables_list_fk_soc'])) + { + $_SESSION['dol_tables_list_fk_soc'] = getTablesWithField('fk_soc', array()); + } + var_dump($_SESSION['dol_tables_list_fk_soc']); +*/ + //$include=false; + //$exclude=false; +/* + $exclude = array( + MAIN_DB_PREFIX . 'user', + MAIN_DB_PREFIX . 'user_employment', + MAIN_DB_PREFIX . 'user_param', + MAIN_DB_PREFIX . 'user_rib', + MAIN_DB_PREFIX . 'user_rights', + MAIN_DB_PREFIX . 'usergroup', + MAIN_DB_PREFIX . 'usergroup_rights', + MAIN_DB_PREFIX . 'usergroup_user', + MAIN_DB_PREFIX . 'rights_def', + ); +*/ + //$exclude = '/(const|user|rights\_def)+/'; + //$include = '/(const|user|rights\_def)+/'; + + //if (empty($_SESSION['dol_tables_list_entity'])) +/* { + $_SESSION['dol_tables_list_entity'] = getTablesWithField('entity', $exclude, $include); + } + + var_dump($_SESSION['dol_tables_list_entity']); +*/ +/* + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED) && ! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array($contextpage, $this->thirdpartycontextlist) || in_array($contextpage, $this->contactcontextlist)) + { + if (GETPOST('confirmmassaction') && GETPOST('massaction') == 'modify_entity') + { + var_dump($_POST['toselect']); + } + } + } +*/ + return 0; + } + + /** + * + */ + public function showLinkedObjectBlock($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + //var_dump($object->linkedObjects); + + foreach($object->linkedObjects as $objecttype => $objects) + { + foreach($objects as $key => $tmpobj) + { + if (empty($tmpobj->entity)) continue; // for debug + + if ($tmpobj->entity != $conf->entity) + { + $element = $objecttype; + if ($objecttype == 'propal') $element = 'proposal'; + if ($objecttype == 'commande') $element = 'order'; + if ($objecttype == 'facture') $element = 'invoice'; + + //var_dump($element);var_dump($mc->sharings[$element]); + //var_dump($object->linkedObjects[$objecttype][$key]); + + if (! empty($mc->sharings[$element]) && in_array($tmpobj->entity, $mc->sharings[$element])) + { + //nothing + } + else + { + unset($object->linkedObjects[$objecttype][$key]); + } + } + } + } + + return 0; + } + + /** + * + */ + public function showLinkToObjectBlock($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + $perms = 1; + $propalperms = 1; + $orderperms = 1 ; + $invoiceperms = 1 ; + + if (in_array('propalcard', $currentcontext) && $object->element == 'propal') + { + if ($object->entity != $conf->entity) + { + $propalperms = ! empty($user->rights->multicompany->propal->write); + } + } + elseif (in_array('ordercard', $currentcontext) && $object->element == 'commande') + { + if ($object->entity != $conf->entity) + { + $orderperms = ! empty($user->rights->multicompany->order->write); + } + } + elseif (in_array('invoicecard', $currentcontext) && $object->element == 'facture') + { + if ($object->entity != $conf->entity) + { + $invoiceperms = ! empty($user->rights->multicompany->invoice->write); + } + } + + $this->results = array('propal' => array('enabled'=>$conf->propal->enabled, 'perms'=>$propalperms, 'label'=>'LinkToProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('propal').')'), + 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>$orderperms, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande').')'), + 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>$invoiceperms, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('invoice').')'), + 'contrat'=>array('enabled'=>$conf->contrat->enabled , 'perms'=>$perms, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'), + 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>$perms, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'), + 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'), + 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'), + 'invoice_supplier'=>array('enabled'=>$conf->supplier_invoice->enabled , 'perms'=>$perms, 'label'=>'LinkToSupplierInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('facture_fourn').')') + ); + + return 1; + } + + /** + * + */ + public function addMoreActionsButtons($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + /*if (in_array('productcard', $currentcontext) && ($object->element == 'product' || $object->element == 'service')) + { + if ($object->entity != $conf->entity) + { + $user->rights->produit->creer = 0; + $user->rights->produit->supprimer = 0; + $user->rights->service->creer = 0; + $user->rights->service->supprimer = 0; + + //return 1; + } + }*/ + + return 0; + } + + /** + * + */ + public function printUserPasswordField($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + + if (empty($conf->multicompany->enabled)) return 0; + + $langs->load('multicompany@multicompany'); + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + $this->resprints = "\n".''."\n"; + + if (in_array('usercard', $currentcontext) && $object->element == 'user' && ! empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX) && checkMulticompanyAutentication()) + { + if ($action == 'create') + { + $this->resprints.= ''; + } + else if ($action == 'edit') + { + if ($caneditpassword) + { + $this->resprints.= ''; + } + else + { + $this->resprints.= preg_replace('/./i','*',$object->pass); + } + } + else + { + if ($object->pass) $this->resprints.= preg_replace('/./i','*',$object->pass); + else + { + if ($user->admin) $this->resprints.= ($valuetoshow?(' '.$langs->trans("or").' '):'').$langs->trans("Crypted").': '.$object->pass_indatabase_crypted; + else $this->resprints.= $langs->trans("Hidden"); + } + } + } + + $this->resprints.= ''."\n"; + + return 0; + } + + /** + * + */ + public function formConfirm($parameters=false, &$object, &$action='') + { + global $conf, $langs; + global $mc, $form; + + if (empty($conf->multicompany->enabled)) return 0; + + $langs->load('multicompany@multicompany'); + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $return = 0; + $currentcontext = explode(':', $parameters['context']); + + $this->resprints = "\n".''."\n"; + + if (in_array('propalcard', $currentcontext) && $object->element == 'propal') + { + if ($action == 'clone' && ! empty($mc->entities['proposal'])) { + // Create an array for form + $formquestion = array( + // 'text' => $langs->trans("ConfirmClone"), + // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')), + array('type' => 'other', 'name' => 'entity', 'label' => $langs->trans("SelectEntity"), 'value' => $mc->select_entities($conf->entity, 'entity', '', false, false, false, explode(',', $mc->entities['proposal']))) + ); + if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->date_livraison)) { + $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->date_livraison); + } + // Incomplete payment. We ask if reason = discount or other + $this->resprints.= $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmClonePropal', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + $return++; + } + } + + $this->resprints.= ''."\n"; + + return $return; + } + + /** + * + */ + public function formObjectOptions($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + global $form; + + if (empty($conf->multicompany->enabled)) return 0; + + $langs->load('multicompany@multicompany'); + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + $this->resprints = "\n".''."\n"; + + if (in_array('thirdpartycard', $currentcontext) && $object->element == 'societe' && ! empty($user->admin) && empty($user->entity)) + { + if ($action == 'create') + { + $this->resprints.= ''.fieldLabel('Entity','entity').''; + $s = $this->select_entities($conf->entity); + $this->resprints.= $form->textwithpicto($s,$langs->trans("ThirdpartyEntityDesc"),1); + $this->resprints.= ''."\n"; + } + } + else if (in_array('contactcard', $currentcontext) && $object->element == 'contact' && ! empty($user->admin) && empty($user->entity)) + { + if ($action == 'create' && empty($objsoc)) + { + $this->resprints.= ''.fieldLabel('Entity','entity').''; + $s = $this->select_entities($conf->entity); + $this->resprints.= $form->textwithpicto($s,$langs->trans("ContactEntityDesc"),1); + $this->resprints.= ''."\n"; + } + } + else if (in_array('usercard', $currentcontext) && $object->element == 'user') + { + if ($action == 'edit') + { + // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !! + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity)) + { + $this->resprints.= ''.$langs->trans("Entity").''; + $this->resprints.= ''.$this->select_entities($object->entity); + $this->resprints.= "\n"; + } + else + { + $this->resprints.= ''; + } + } + else if ($action == 'create') + { + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity)) + { + $this->resprints.= ''.$langs->trans("Entity").''; + $this->resprints.= ''.$this->select_entities($conf->entity); + $this->resprints.= "\n"; + } + else + { + $this->resprints.= ''; + } + } + else if ($action != 'adduserldap') + { + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity)) + { + $this->resprints.= ''.$langs->trans("Entity").''; + if (empty($object->entity)) + { + $this->resprints.= $langs->trans("AllEntities"); + } + else + { + $this->getInfo($object->entity); + $this->resprints.= $this->label; + } + $this->resprints.= "\n"; + } + } + } + else if ((in_array('propalcard', $currentcontext) && $object->element == 'propal') + || (in_array('ordercard', $currentcontext) && $object->element == 'commande') + || (in_array('invoicecard', $currentcontext) && $object->element == 'facture') + ) + { + if ($action == 'create') + { + $this->resprints.= ''.$langs->trans("Entity").''; + $this->resprints.= ''.$this->select_entities($conf->entity); + $this->resprints.= "\n"; + } + } + + $this->resprints.= ''."\n"; + + return 0; + } + + /** + * + */ + public function formCreateThirdpartyOptions($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + global $form; + + if (empty($conf->multicompany->enabled)) return 0; + + $langs->load('multicompany@multicompany'); + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + //echo 'OK'; + + //$this->resprints = 'OK'; + + return 0; + } + + /** + * + */ + public function formAddUserToGroup($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + global $form, $mc, $exclude; + + if (empty($conf->multicompany->enabled)) return 0; + + $langs->load('multicompany@multicompany'); + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + $this->resprints = ''; + + if (is_array($currentcontext)) + { + if (in_array('usercard', $currentcontext) && $object->element == 'user') + { + if ($action != 'edit' && $action != 'presend' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $this->resprints = "\n".''."\n"; + + if (! empty($groupslist)) + { + $exclude=array(); + } + + if ($caneditgroup) + { + $this->resprints.= '
'."\n"; + $this->resprints.= ''; + $this->resprints.= ''; + } + $this->resprints.= ''."\n"; + + $this->resprints.= ''."\n"; + if (! empty($user->admin)) + { + $this->resprints.= ''; + } + $this->resprints.= ''."\n"; + + /* + * Groups assigned to user + */ + if (! empty($groupslist)) + { + foreach($groupslist as $group) + { + $this->resprints.= ''; + $this->resprints.= ''; + if (! empty($user->admin)) + { + $this->resprints.= ''."\n"; + } + } + else + { + $this->resprints.= ''; + } + + $this->resprints.= "
'.$langs->trans("Groups").''.$langs->trans("Entity").''; + if ($caneditgroup && empty($user->entity)) + { + // Users/Groups management only in master entity if transverse mode + if ($conf->entity == 1) + { + $this->resprints.= $form->select_dolgroups('', 'group', 1, $exclude, 0, '', '', $object->entity); + $this->resprints.= '   '; + if ($conf->entity == 1) + { + $entities = $this->getEntitiesList(); + $this->resprints.= $form->multiselectarray('entities', $entities, GETPOST('entities', 'array'), '', 0, '', 0, '20%'); + } + else + { + $this->resprints.= ''; + } + $this->resprints.= ''; + } + } + $this->resprints.= '
'; + if ($caneditgroup) + { + $this->resprints.= ''.img_object($langs->trans("ShowGroup"),"group").' '.$group->name.''; + } + else + { + $this->resprints.= img_object($langs->trans("ShowGroup"),"group").' '.$group->name; + } + $this->resprints.= ''; + if (! empty($group->usergroup_entity)) + { + $nb=0; + foreach($group->usergroup_entity as $group_entity) + { + $mc->getInfo($group_entity); + if (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && $mc->visible == 2) continue; + + $this->resprints.= ''; + if ($mc->visible == 2) { + $this->resprints.= ''; + } else { + $this->resprints.= ''; + } + $this->resprints.= $mc->label . (empty($mc->active) ? ' ('.$langs->trans('Disabled').')' : ($mc->visible == 2 ? ' ('.$langs->trans('Template').')' : (empty($mc->visible) ? ' ('.$langs->trans('Hidden').')' : '')) ); + if ($conf->entity == 1 && empty($user->entity)) { + $this->resprints.= ''; + $this->resprints.= img_picto($langs->trans("RemoveFromGroup"), 'unlink'); + $this->resprints.= ''; + } + $this->resprints.= ''; + } + } + } + $this->resprints.= ' 
'.$langs->trans("None").'
"; + + if ($caneditgroup) + { + $this->resprints.= '
'; + } + + $this->resprints.= ''."\n"; + + return 1; + } + } + else if (in_array('groupcard', $currentcontext) && $object->element == 'usergroup') + { + if ($action != 'edit' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $this->resprints = "\n".''."\n"; + + if (! empty($object->members)) + { + $exclude=array(); + } + + if ($caneditperms && empty($user->entity)) + { + $this->resprints.= '
'."\n"; + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''."\n"; + $this->resprints.= ''."\n"; + $this->resprints.= ''."\n"; + $this->resprints.= '
'.$langs->trans("NonAffectedUsers").''; + $this->resprints.= $form->select_dolusers('', 'user', 1, $exclude, 0, '', '', $object->entity); + $this->resprints.= '   '; + if ($conf->entity == 1) + { + $entities = $this->getEntitiesList(false, false, false, (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) ? false : true)); + $this->resprints.= $form->multiselectarray('entities', $entities, GETPOST('entities', 'array'), '', 0, '', 0, '20%'); + } + else + { + $this->resprints.= ''; + } + $this->resprints.= ''; + $this->resprints.= '
'."\n"; + $this->resprints.= '
'; + } + + /* + * Group members + */ + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''; + if ($conf->entity == 1) + { + $this->resprints.= ''; + } + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= "\n"; + + if (! empty($object->members)) + { + foreach($object->members as $useringroup) + { + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''; + $this->resprints.= ''; + if ($conf->entity == 1 && ! empty($user->admin)) + { + $this->resprints.= ''; + } + $this->resprints.= ''; + $this->resprints.= '\n"; + } + } + else + { + $this->resprints.= ''; + } + $this->resprints.= "
'.$langs->trans("Login").''.$langs->trans("Lastname").''.$langs->trans("Firstname").''.$langs->trans("Entity").''.$langs->trans("Status").' 
'; + $this->resprints.= $useringroup->getNomUrl(-1, '', 0, 0, 24, 0, 'login'); + if ($useringroup->admin && ! $useringroup->entity) $this->resprints.= img_picto($langs->trans("SuperAdministrator"),'redstar'); + else if ($useringroup->admin) $this->resprints.= img_picto($langs->trans("Administrator"),'star'); + $this->resprints.= ''.$useringroup->lastname.''.$useringroup->firstname.''; + if (! empty($useringroup->usergroup_entity)) + { + foreach($useringroup->usergroup_entity as $group_entity) + { + $mc->getInfo($group_entity); + if (empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && $mc->visible == 2) continue; + + $this->resprints.= ''; + if ($mc->visible == 2) { + $this->resprints.= ''; + } else { + $this->resprints.= ''; + } + $this->resprints.= $mc->label . (empty($mc->active) ? ' ('.$langs->trans('Disabled').')' : ($mc->visible == 2 ? ' ('.$langs->trans('Template').')' : (empty($mc->visible) ? ' ('.$langs->trans('Hidden').')' : '')) ); + if (empty($user->entity)) { + $this->resprints.= ''; + $this->resprints.= img_picto($langs->trans("RemoveFromGroup"), 'unlink'); + $this->resprints.= ''; + } + $this->resprints.= ''; + } + } + $this->resprints.= ''.$useringroup->getLibStatut(3).''; + $this->resprints.= "-"; + $this->resprints.= "
'.$langs->trans("None").'
"; + + $this->resprints.= ''."\n"; + + return 1; + } + } + } + + return 0; + } + + /** + * + */ + public function moreHtmlRef($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + $this->resprints = "\n".''."\n"; + + // if global sharings is enabled + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + $this->getInfo(! empty($object->entity) ? $object->entity : $conf->entity); + + // if third party sharing is enabled (is mandatory for some sharings) + if (! empty($conf->societe->enabled) && ! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if ($object->element == 'societe') + { + if (in_array('thirdpartycard', $currentcontext)) + { + if ($action != 'create' && $action != 'edit') + { + if ($object->isObjectUsed($object->id) === 0 && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->thirdparty->write))) + { + $selectEntities = $this->getModifyEntityDialog('thirdparty', 'modifyEntity', $object); + + if (! empty($selectEntities)) { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + $this->resprints.= $selectEntities; + } else { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + else + { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + } + else + { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + else if ($object->element == 'contact') + { + if (in_array('contactcard', $currentcontext)) + { + if ($action != 'create' && $action != 'edit') + { + if (empty($object->socid) && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->contact->write))) + { + $selectEntities = $this->getModifyEntityDialog('contact', 'modifyEntity', $object); + + if (! empty($selectEntities)) { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + $this->resprints.= $selectEntities; + } else { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + else + { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + } + else + { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + } + + if (((! empty($conf->product->enabled) || ! empty($conf->service->enabled)) && $object->element == 'product' && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + || (! empty($conf->propal->enabled) && $object->element == 'propal' && in_array('propalcard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + || (! empty($conf->commande->enabled) && $object->element == 'commande' && in_array('ordercard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + || (! empty($conf->facture->enabled) && $object->element == 'facture' && in_array('invoicecard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + || (! empty($conf->stock->enabled) && $object->element == 'stock' && in_array('warehousecard', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock'])) + ) + { + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + + if ($object->element == 'user' || $object->element == 'usergroup') + { + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && ! empty($user->admin) && empty($user->entity)) + { + $this->getInfo($object->entity); + $this->resprints.= '
'; + $this->resprints.= ''.$this->label.''; + $this->resprints.= '
'; + } + } + + $this->resprints.= ''."\n"; + + return 0; + } + + /** + * + */ + public function moreHtmlStatus($parameters=false, &$object, &$action='') + { + global $conf, $user; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + //$this->resprints.= 'OK'; + + return 0; + } + + /** + * + */ + public function printUserListWhere($parameters=false) + { + global $conf, $user; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $this->resprints = ''; + + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) { + $this->resprints.= " WHERE u.entity IS NOT NULL"; // Show all users + } else { + $this->resprints.= ",".MAIN_DB_PREFIX."usergroup_user as ug"; + $this->resprints.= " WHERE ((ug.fk_user = u.rowid"; + $this->resprints.= " AND ug.entity IN (".getEntity('usergroup')."))"; + $this->resprints.= " OR u.entity = 0)"; // Show always superadmin + } + return 1; + } + + return 0; + } + + /** + * + * @return number + */ + public function addMoreMassActions($parameters=false) + { + global $conf, $user, $langs; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + // name="massaction" + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext)) + { + $langs->load('multicompany@multicompany'); + $this->resprints = ''; + } + } + } + + return 0; + } + + /** + * + * @return number + */ + public function printFieldListSelect($parameters=false) + { + global $conf; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + // Thirdparty sharing is mandatory to share document (propal, etc...) + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext)) + { + //if (! empty($arrayfields['s.entity']['checked'])) + { + $this->resprints = ", s.entity"; + } + } + else if (in_array('contactlist', $currentcontext)) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = ", p.entity"; + } + } + else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = ", p.entity"; + } + } + else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = ", c.entity"; + } + } + else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = ", f.entity"; + } + } + } + + if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = ", p.entity"; + } + } + } + + return 0; + } + + /** + * + * @param boolean $parameters + * @return number + */ + public function printFieldListWhere($parameters=false) + { + global $conf; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext)) + { + //if (! empty($arrayfields['s.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND s.entity = " . $search_entity; + } + } + } + else if (in_array('contactlist', $currentcontext)) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND p.entity = " . $search_entity; + } + } + } + else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND p.entity = " . $search_entity; + } + } + } + else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND c.entity = " . $search_entity; + } + } + } + else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + { + //if (! empty($arrayfields['f.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND f.entity = " . $search_entity; + } + } + } + } + + if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND p.entity = " . $search_entity; + } + } + } + if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + if ($search_entity > 0) + { + $this->resprints = " AND t.entity = " . $search_entity; + } + } + } + } + + return 0; + } + + /** + * + * @param boolean $parameters + * @return number + */ + public function printFieldListOption($parameters=false) + { + global $conf; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext)) + { + //if (! empty($arrayfields['s.entity']['checked']) || ! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['thirdparty']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['proposal']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['order']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + { + //if (! empty($arrayfields['f.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['invoice']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + } + + if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['product']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $search_entity = GETPOST('search_entity','int'); + + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers + { + $search_entity = ''; + } + + // Entity + $this->resprints = ''; + $this->resprints.= $this->select_entities($search_entity,'search_entity','',false,false,true,explode(",", $mc->entities['stock']),'','minwidth100imp'); + $this->resprints.= ''; + } + } + } + + return 0; + } + + /** + * + * @param boolean $parameters + * @return number + */ + public function printFieldListTitle($parameters=false) + { + global $conf; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext)) + { + //if (! empty($arrayfields['s.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"s.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + else if (in_array('contactlist', $currentcontext)) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"c.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + { + //if (! empty($arrayfields['f.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"f.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + } + + if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"p.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + + if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->resprints = getTitleFieldOfList('Entity',0,$_SERVER["PHP_SELF"],"t.entity","",$param,'align="center"',$sortfield,$sortorder); + } + } + } + + return 0; + } + + /** + * + * @param boolean $parameters + * @return number + */ + public function printFieldListValue($parameters=false) + { + global $conf; + global $totalarray; + global $mc; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + if (! empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED) && ! empty($mc->sharings['thirdparty'])) + { + if (in_array('thirdpartylist', $currentcontext) || in_array('contactlist', $currentcontext)) + { + //if (! empty($arrayfields['s.entity']['checked']) || ! empty($arrayfields['p.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + } + } + else if (in_array('propallist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PROPOSAL_SHARING_ENABLED) && ! empty($mc->sharings['proposal'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + if (! $i) $totalarray['nbfield']++; + } + } + else if (in_array('orderlist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_ORDER_SHARING_ENABLED) && ! empty($mc->sharings['order'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + if (! $i) $totalarray['nbfield']++; + } + } + else if (in_array('invoicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) && ! empty($mc->sharings['invoice'])) + { + //if (! empty($arrayfields['f.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + if (! $i) $totalarray['nbfield']++; + } + } + } + + if (in_array('productservicelist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_PRODUCT_SHARING_ENABLED) && ! empty($mc->sharings['product'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + } + } + + if (in_array('stocklist', $currentcontext) && ! empty($conf->global->MULTICOMPANY_STOCK_SHARING_ENABLED) && ! empty($mc->sharings['stock'])) + { + //if (! empty($arrayfields['p.entity']['checked'])) + { + $this->getInfo($obj->entity); + $this->resprints = ''.$this->label."\n"; + } + } + } + + return 0; + } + + /** + * + */ + public function insertExtraHeader($parameters=false, &$object, &$action='') + { + global $conf, $user, $langs; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if (in_array('userperms', $currentcontext) || in_array('groupperms', $currentcontext)) + { + $this->getInstanceDao(); + + if ($object->element == 'user') + { + $aEntities=array_keys($permsgroupbyentity); + + // Check usergroup if user not in master entity + if (empty($aEntities) || ! array_key_exists(1, $permsgroupbyentity)) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + $aEntities=array(); + $group = new UserGroup($this->db); + $ret = $group->listGroupsForUser($object->id, false); + if (! empty($ret)) { + foreach($ret as $groupid => $data) + { + $aEntities = array_merge($aEntities, $data->usergroup_entity); + } + sort($aEntities); + } + } + + if (! empty($aEntities)) + { + $entity = (GETPOST('entity', 'int')?GETPOST('entity', 'int'):$aEntities[0]); + $head = entity_prepare_head($object, $aEntities); + $title = $langs->trans("Entities"); + dol_fiche_head($head, $entity, $title, 1, 'multicompany@multicompany'); + } + else + { + print get_htmloutput_mesg(img_warning('default') . ' ' . $langs->trans("ErrorLinkUserGroupEntity"), '', 'mc-upgrade-alert', 1); + } + } + else if ($object->element == 'usergroup') + { + $this->dao->getEntities(); + $aEntities=array(); + + foreach ($this->dao->entities as $objEntity) + { + $aEntities[] = $objEntity->id; + } + + $entity = (GETPOST('entity', 'int')?GETPOST('entity', 'int'):$aEntities[0]); + $head = entity_prepare_head($object, $aEntities); + $title = $langs->trans("Entities"); + dol_fiche_head($head, $entity, $title, 1, 'multicompany@multicompany'); + + if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) { + print ' +
+

'.img_info().' '.$langs->transnoentities('DuplicateRightsInfo').'

+

'.$langs->transnoentities('SelectRightsOfEntityToDuplicate').' '.$this->select_entities('', 'template', '', false, false, false, false, '', 'minwidth200imp', true, true).'

+

'.$langs->transnoentities('SelectEntitiesToOverride').'

+

+
+
+
'.$langs->transnoentities("EntitiesSelected").'
+ '.$this->multiselectEntitiesToOverride('overrideentities', true).' +
+
+ + + + + + +
+
+
'.$langs->transnoentities("EntitiesAvailable").'
+ '.$this->multiselectEntitiesToOverride('overrideentities', false).' +
+
+

+
+ + '; + } + } + + // Check if advanced perms is enabled for current object entity + $res = $this->dao->getEntityConfig($entity, 'MAIN_USE_ADVANCED_PERMS'); + if (empty($res['MAIN_USE_ADVANCED_PERMS'])) { + unset($conf->global->MAIN_USE_ADVANCED_PERMS); + } + } + } + + return 0; + } + + /** + * + */ + public function insertExtraFooter($parameters=false, &$object, &$action='') + { + global $conf, $user; + + if (empty($conf->multicompany->enabled)) return 0; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key=>$value) + { + $$key=$value; + } + } + + $currentcontext = explode(':', $parameters['context']); + + if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1 && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if (in_array('userperms', $currentcontext) || in_array('groupperms', $currentcontext)) + { + // Restore advanced perms if enabled for current entity + $this->getInstanceDao(); + $res = $this->dao->getEntityConfig($conf->entity, 'MAIN_USE_ADVANCED_PERMS'); + if (! empty($res['MAIN_USE_ADVANCED_PERMS'])) { + $conf->global->MAIN_USE_ADVANCED_PERMS = $res['MAIN_USE_ADVANCED_PERMS']; + } + } + } + + return 0; + } + + /** + * Return combo list of entities. + * + * @param int $selected Preselected entity + * @param int $htmlname Name + * @param string $option Option + * @param boolean $login If use in login page or not + * @param boolean $exclude Exclude + * @param boolean $emptyvalue Emptyvalue + * @param boolean $only Only + * @param string $all Add 'All entities' value in combo list + * @param string $cssclass specific css class. eg 'minwidth150imp mycssclass' + * @param bool $ajax Enable ajax combobox + * @param bool $template Show template of entities + * @return string + */ + public function select_entities($selected = '', $htmlname = 'entity', $option = '', $login = false, $exclude = false, $emptyvalue = false, $only = false, $all = '', $cssclass = 'minwidth150imp', $ajax = true, $template = false) + { + global $conf, $user, $langs; + + $this->getInstanceDao(); + + $this->dao->getEntities($login, $exclude); + + $out = ''; + + if (is_array($this->dao->entities) && ! empty($this->dao->entities)) + { + $out.= ''; + + // Make select dynamic + if ($ajax) { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $out.= ajax_combobox($htmlname); + } + } + + return $out; + } + + /** + * Return multiselect list of entities. + * + * @param string $htmlname Name of select + * @param DaoMulticompany $current Current entity to manage + * @param bool $onlyselected true: show only selected, false: hide only selected + * @return string + */ + public function multiselect_entities($htmlname, $current, $onlyselected=false) + { + global $langs; + + $this->getInstanceDao(); + $this->dao->getEntities(); + + $selectname = ($onlyselected ? $htmlname.'_to[]' : 'from[]'); + $selectid = ($onlyselected ? 'multiselect_shared_'.$htmlname.'_to' : 'multiselect_shared_'.$htmlname); + + $return = ''; + + return $return; + } + + /** + * Return multiselect list of entities to override. + * + * @param string $htmlname Name of select + * @param bool $onlyselected true: show only selected, false: hide only selected + * @return string + */ + public function multiselectEntitiesToOverride($htmlname, $onlyselected=false) + { + global $langs; + + $this->getInstanceDao(); + $this->dao->getEntities(); + + $selectname = ($onlyselected ? $htmlname.'_to[]' : 'from[]'); + $selectid = ($onlyselected ? 'multiselect_'.$htmlname.'_to' : 'multiselect_'.$htmlname); + + $out = ''; + + return $out; + } + + /** + * Return multiselect list of entities. + * + * @param string $htmlname Name of select + * @param array $selected Entities already selected + * @param string $option Option + * @return string + */ + public function multiSelectEntities($htmlname, $selected=null, $option=null) + { + global $langs; + + $this->getInstanceDao(); + $this->dao->getEntities(); + + $return = ''; + + return $return; + } + + /** + * Switch to another entity. + * + * @param int $id User id + * @param int $entity Entity id + * @return int + */ + public function checkRight($id, $entity) + { + global $user; + + $this->getInstanceDao(); + + if ($this->dao->fetch($entity) > 0) + { + // Controle des droits sur le changement + if ($this->dao->verifyRight($entity, $id) || $user->admin) + { + return 1; + } + else + { + return -2; + } + } + else + { + return -1; + } + } + + /** + * Switch to another entity. + * @param int $id Id of the destination entity + * @param int $userid + * @return int + */ + public function switchEntity($id, $userid=null) + { + global $conf, $user; + + $this->getInstanceDao(); + + if (!empty($userid)) + { + $user=new User($this->db); + $user->fetch($userid); + } + + if ($this->dao->fetch($id) > 0 && ! empty($this->dao->active)) // check if the entity is still active + { + // Controle des droits sur le changement + if (!empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX) + || (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $this->dao->verifyRight($id, $user->id)) + || $user->admin) + { + $_SESSION['dol_entity'] = $id; + //$conf = new Conf(); FIXME some constants disappear + $conf->entity = $id; + $conf->setValues($this->db); + return 1; + } + else + { + //var_dump($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX); + //var_dump($conf->global->MULTICOMPANY_TRANSVERSE_MODE); + //var_dump($this->dao->verifyRight($id, $user->id)); + return -2; + } + } + else + { + return -1; + } + } + + /** + * Get entity info + * @param int $id Object id + */ + public function getInfo($id) + { + $this->getInstanceDao(); + $this->dao->fetch($id); + + $this->id = $this->dao->id; + $this->label = $this->dao->label; + $this->country_id = $this->dao->country_id; + $this->country_code = $this->dao->country_code; + $this->currency_code = $this->dao->currency_code; + $this->language_code = $this->dao->language_code; + $this->description = $this->dao->description; + $this->options = $this->dao->options; + $this->active = $this->dao->active; + $this->visible = $this->dao->visible; + } + + /** + * Get action title + * @param string $action Type of action + * @return string + */ + public function getTitle($action='') + { + global $langs; + + if ($action == 'create') return $langs->trans("AddEntity"); + else if ($action == 'edit') return $langs->trans("EditEntity"); + else return $langs->trans("EntitiesManagement"); + } + + + /** + * Assigne les valeurs pour les templates + * @param string $action Type of action + */ + public function assign_values($action='view') + { + global $conf, $langs, $user; + global $form, $formcompany, $formadmin; + + require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; + + $this->tpl['extrafields'] = new ExtraFields($this->db); + // fetch optionals attributes and labels + $this->tpl['extralabels'] = $this->tpl['extrafields']->fetch_name_optionals_label('entity'); + + $this->getInstanceDao(); + + $this->template_dir = dol_buildpath('/multicompany/admin/tpl/'); + $this->template = 'list.tpl.php'; + + if ($action == 'create' || $action == 'edit') + { + $this->template = 'card.tpl.php'; + + if ($action == 'edit' && GETPOSTISSET('id')) { + $ret = $this->dao->fetch(GETPOST('id', 'int')); + } + + if (! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT)) + { + $templatevalue = (GETPOSTISSET('template') ? GETPOST('template', 'int') : ($this->dao->visible === '2' ? 1 : 0)); + + if ($action == 'create') { + $this->tpl['template'] = $form->selectyesno('template', $templatevalue, 1); + $this->tpl['select_template'] = $this->select_entities('','usetemplate','',false,false,true,'','','minwidth200imp',true,'only'); + } elseif ($templatevalue === 1) { + $this->tpl['template'] = $templatevalue; + } + } + + // action + $this->tpl['action'] = $action; + + // id + $this->tpl['id'] = (GETPOSTISSET('id')?GETPOST('id', 'int'):null); + + // Label + $this->tpl['label'] = (GETPOSTISSET('label')?GETPOST('label', 'alpha'):$this->dao->label); + + // Description + $this->tpl['description'] = (GETPOSTISSET('description')?GETPOST('description', 'alpha'):$this->dao->description); + + // Company name + $this->tpl['name'] = (GETPOSTISSET('name')?GETPOST('name', 'alpha'):$this->dao->name); + + // Address + $this->tpl['address'] = (GETPOSTISSET('address')?GETPOST('address', 'alpha'):$this->dao->address); + + // Zip + $this->tpl['select_zip'] = $formcompany->select_ziptown((GETPOSTISSET('zipcode')?GETPOST('zipcode', 'alpha'):$this->dao->zip),'zipcode',array('town','selectcountry_id','departement_id'),6); + + // Town + $this->tpl['select_town'] = $formcompany->select_ziptown((GETPOSTISSET('town')?GETPOST('town', 'alpha'):$this->dao->town),'town',array('zipcode','selectcountry_id','departement_id'),40); + + if ($user->admin) $this->tpl['info_admin'] = info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + + + // We define country_id + if (GETPOSTISSET('country_id')) + { + $country_id = GETPOST('country_id', 'int'); + } + else if (! empty($this->dao->country_id)) + { + $country_id = $this->dao->country_id; + } + else if (! empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) + { + $tmp = explode(':', $conf->global->MAIN_INFO_SOCIETE_COUNTRY); + $country_id = $tmp[0]; + } + else + { + $country_id = 0; + } + + $this->tpl['select_country'] = $form->select_country($country_id,'country_id'); + $this->tpl['select_state'] = $formcompany->select_state((GETPOSTISSET('departement_id')?GETPOST('departement_id', 'int'):$this->dao->state_id),$country_id,'departement_id'); + $this->tpl['select_currency'] = $form->selectCurrency((GETPOSTISSET('currency_code')?GETPOST('currency_code', 'alpha'):($this->dao->currency_code?$this->dao->currency_code:$conf->currency)),"currency_code"); + $this->tpl['select_language'] = $formadmin->select_language((GETPOSTISSET('main_lang_default')?GETPOST('main_lang_default', 'alpha'):($this->dao->language_code?$this->dao->language_code:$conf->global->MAIN_LANG_DEFAULT)),'main_lang_default',1); + + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) { + foreach ($this->sharingelements as $element => $params) { + if ((($params['object'] || $params['objectnumber']) && ! isset($params['disable'])) && (empty($conf->societe->enabled) || empty($conf->global->MULTICOMPANY_THIRDPARTY_SHARING_ENABLED))) continue; + $uppername = strtoupper($element); + $constname = 'MULTICOMPANY_' . $uppername . '_SHARING_ENABLED'; + if (! empty($conf->global->$constname)) { + $this->tpl['multiselect_from_' . $element] = $this->multiselect_entities($element, $this->dao, false); + $this->tpl['multiselect_to_' . $element] = $this->multiselect_entities($element, $this->dao, true); + if ($element == 'proposalnumber' || $element == 'invoicenumber') { + $this->tpl['select_'.$element.'_entity'] = $this->select_entities($this->dao->options[$element.'_referent'], $element.'_referring_entity'); + } + $addtoallother = (GETPOSTISSET('addtoallother_' . $element) ? GETPOST('addtoallother_' . $element, 'int') : $this->dao->options['addtoallother'][$element]); + $this->tpl['addtoallother_' . $element] = $form->selectyesno('addtoallother_' . $element, $addtoallother, 1); + } + } + } + } + } + + /** + * Display the template + */ + public function display() + { + global $conf, $langs; + global $form, $object; + + include $this->template_dir.$this->template; + } + + /** + * Set values of global conf for multicompany + * + * @param Conf $conf Object conf + * @return void + */ + public function setValues(&$conf) + { + if (! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)) + { + $this->getInstanceDao(); + $this->dao->fetch($conf->entity); + + $this->sharings = $this->dao->options['sharings']; + //$this->referent = $this->dao->options['referent']; + $this->proposalnumber_referent = (isset($this->dao->options['proposalnumber_referent'])?$this->dao->options['proposalnumber_referent']:''); + $this->invoicenumber_referent = (isset($this->dao->options['invoicenumber_referent'])?$this->dao->options['invoicenumber_referent']:''); + + // Load shared elements + $this->loadSharedElements(); + + // Define output dir for others entities + $this->setMultiOutputDir($conf); + } + + if (! empty($this->sharingdicts)) + { + foreach($this->sharingdicts as $dict => $data) + { + $constname = 'MULTICOMPANY_'.strtoupper($dict).'_SHARING_DISABLED'; + if (! empty($conf->global->$constname)) { + $this->dict[$dict] = true; + } + } + } + } + + /** + * Set status of an entity + * + * @param int $id Id of entity + * @param string $type Type of status (visible or active) + * @param string $value Value of status (0: disable, 1: enable) + * @return int + */ + public function setStatus($id, $type='active', $value) + { + global $user; + + if (! empty($user->admin) && ! $user->entity) { + $this->getInstanceDao(); + return $this->dao->setEntity($id, $type, $value); + } + else { + return -1; + } + } + + /** + * Delete an entity + * + * @param int $id Id of entity + * @return int + */ + public function deleteEntity($id) + { + global $user; + + if (! empty($user->admin) && ! $user->entity && $id != 1) { + $this->getInstanceDao(); + return $this->dao->delete($id); + } + else { + return -1; + } + } + + /** + * Get list of entity id to use. + * + * @param string $element Current element + * 'societe', 'socpeople', 'actioncomm', 'agenda', 'resource', + * 'product', 'productprice', 'stock', + * 'propal', 'supplier_proposal', 'invoice', 'facture_fourn', 'payment_various', + * 'categorie', 'bank_account', 'bank_account', 'adherent', 'user', + * 'commande', 'commande_fournisseur', 'expedition', 'intervention', 'survey', + * 'contract', 'tax', 'expensereport', 'holiday', 'multicurrency', 'project', + * 'email_template', 'event', 'donation' + * 'c_paiement', 'c_payment_term', ... + * @param int $shared 0=Return id of current entity only, + * 1=Return id of current entity + shared entities (default) + * @param object $currentobject Current object if needed + * @return mixed Entity id(s) to use ( eg. entity IN ('.getEntity(elementname).')' ) + */ + public function getEntity($element=false, $shared=1, $currentobject=null) + { + global $conf, $user; + + $element = str_replace(MAIN_DB_PREFIX, '', $element); + + if (in_array($element, $this->addzero)) + { + if ($element == 'user' && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + return '0,1'; // In transverse mode all users except superadmin and groups are in entity 1 + } else { + if ($element == 'usergroup' && $conf->entity == 1 && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && !empty($user->admin) && empty($user->entity)) + { + return '0,'.implode(',', array_keys($this->getEntitiesList(true, false, true))); // Superadmin can always edit groups of another entities + } + + return '0,'.$conf->entity; + } + } + + // Sharing dictionnaries + if (array_key_exists($element, $this->sharingdicts)) + { + if (! empty($this->dict[$element])) { + return $conf->entity; + } else { + return 1; // Master entity + } + } + + // Check object entity when number sharing is disabled + if (is_object($currentobject) && + (($element == 'proposalnumber' && empty($conf->global->MULTICOMPANY_PROPOSALNUMBER_SHARING_ENABLED)) + || ($element == 'ordernumber' && empty($conf->global->MULTICOMPANY_ORDERNUMBER_SHARING_ENABLED)) + || ($element == 'invoicenumber' && empty($conf->global->MULTICOMPANY_INVOICENUMBER_SHARING_ENABLED)) + ) + ) + { + // Use object entity ID + $entity = ((isset($currentobject->entity) && is_numeric($currentobject->entity)) ? $currentobject->entity : $conf->entity); + return $entity; + } + + $elementkey = $element; + if ($element == 'societe' || $element == 'socpeople' || $element == 'contact') { + $elementkey = 'thirdparty'; + } + if ($element == 'adherent') $elementkey = 'member'; + if ($element == 'bank_account') $elementkey = 'bankaccount'; + if ($element == 'adherent_type') $elementkey = 'member_type'; + if ($element == 'categorie') $elementkey = 'category'; + if ($element == 'propal') $elementkey = 'proposal'; + if ($element == 'commande') $elementkey = 'order'; + if ($element == 'facture') $elementkey = 'invoice'; + + if (! empty($element) && ! empty($this->entities[$elementkey])) + { + if (! empty($shared)) + { + return $this->entities[$elementkey]; + } + else if (! empty($this->sharings['referent'])) + { + if ($element == 'societe') return $this->sharings['referent']; + } + } + + return $conf->entity; + } + + /** + * Set entity id to use when to create an object + * + * @param object $currentobject Current object + * @return int Entity id to use + */ + public function setEntity($currentobject) + { + global $conf; + + $entity = $conf->entity; + + if (is_object($currentobject) && ! empty($currentobject->element)) + { + $element = array_search($currentobject->element, $this->sharingmodulename); + $element = (! empty($element) ? $element : $currentobject->element); + $constname = 'MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED'; + $newentity = $entity; + + if (isset($this->sharingelements[$element]) + && isset($this->sharingelements[$element]['active']) + && ! empty($conf->global->$constname) + ) + { + if (GETPOSTISSET('entity') && GETPOST('entity', 'int', 2)) + { + $newentity = GETPOST('entity', 'int', 2); + } + else if (isset($currentobject->entity) && is_numeric($currentobject->entity)) + { + $newentity = $currentobject->entity; + } + + if (isset($this->sharings[$element]) && in_array($newentity, $this->sharings[$element])) + { + $entity = $newentity; + } + } + else + { + $entity = (($currentobject->id > 0 && $currentobject->entity > 0) ? $currentobject->entity : $conf->entity); + } + } + + return $entity; + } + + /** + * Get entities list + * + * @param int $login If use in login page or not + * @param array $exclude Entity ids to exclude + * @param bool $onlyactive sort only active entities + * @param bool $showtemplate Show or not templates + * @return array Array of entities (id => label) + */ + public function getEntitiesList($login = false, $exclude = false, $onlyactive = false, $showtemplate = false) + { + global $langs; + + $this->getInstanceDao(); + $this->dao->getEntities($login, $exclude, $onlyactive); + + $entities=array(); + + foreach ($this->dao->entities as $entity) + { + if (empty($showtemplate) && $entity->visible == 2) continue; + $entities[$entity->id] = dol_html_entity_decode($entity->label, null) . (empty($entity->active) ? ' ('.$langs->transnoentities('Disabled').')' : ($entity->visible == 2 ? ' ('.$langs->transnoentities('Template').')' : (empty($entity->visible) ? ' ('.$langs->transnoentities('Hidden').')' : '')) ); + } + + return $entities; + } + + /** + * Set object documents directory to use + * + * @param Conf $conf Object Conf + * @return void + */ + public function setMultiOutputDir(&$conf) + { + if (! empty($this->entities)) + { + foreach($this->entities as $element => $shares) + { + if ($element == 'thirdparty') $element = 'societe'; + elseif ($element == 'member') $element = 'adherent'; + elseif ($element == 'proposal') $element = 'propal'; + elseif ($element == 'order') $element = 'commande'; + elseif ($element == 'invoice') $element = 'facture'; + elseif ($element == 'intervention') $element = 'ficheinter'; + + if (! empty($conf->$element->enabled) && isset($conf->$element->multidir_output) && isset($conf->$element->multidir_temp)) + { + $elementpath=$element; + if ($element == 'product') $elementpath='produit'; + elseif ($element == 'category') $elementpath='categorie'; + elseif ($element == 'propal') $elementpath='propale'; + + $entities = explode(",", $shares); + $dir_output = array(); + $dir_temp = array(); + foreach($entities as $entity) + { + if (! array_key_exists($entity, $conf->$element->multidir_output)) + { + $path = ($entity > 1 ? "/".$entity : ''); + + $dir_output[$entity] = DOL_DATA_ROOT.$path."/".$elementpath; + $dir_temp[$entity] = DOL_DATA_ROOT.$path."/".$elementpath."/temp"; + + $conf->$element->multidir_output += $dir_output; + $conf->$element->multidir_temp += $dir_temp; + } + + if (in_array($element, array('propal', 'commande', 'facture')) && isset($conf->mycompany->multidir_output)) + { + if (! array_key_exists($entity, $conf->mycompany->multidir_output)) + { + $path = ($entity > 1 ? "/".$entity : ''); + + $dir_output[$entity] = DOL_DATA_ROOT.$path."/mycompany"; + $dir_temp[$entity] = DOL_DATA_ROOT.$path."/mycompany/temp"; + + $conf->mycompany->multidir_output += $dir_output; + $conf->mycompany->multidir_temp += $dir_temp; + } + } + } + } + } + } + } + + /** + * @param bool $parameters + * @return int + */ + public function printTopRightMenu($parameters=false) + { + echo $this->getTopRightMenu(); + + return 0; + } + + /** + * + */ + public function printBugtrackInfo($parameters=false) + { + global $conf; + + if (! empty($conf->multicompany->enabled)) { + $this->resprints = urlencode("- **Multicompany**: " . $conf->global->MULTICOMPANY_MAIN_VERSION . "\n"); + } + + return 0; + } + + /** + * @param bool $parameters + * @return int + */ + /*public function afterLogin($parameters=false) + { + global $conf; + + return 0; + }*/ + + /** + * @param bool $parameters + * @return int + */ + public function updateSession($parameters=false) + { + global $conf; + + // Switch to another entity + if (! empty($conf->multicompany->enabled) && GETPOST('action','aZ') == 'switchentity') + { + if ($this->switchEntity(GETPOST('entity','int')) > 0) + { + header("Location: ".DOL_URL_ROOT.'/'); + exit; + } + } + + return 0; + } + + /** + * + */ + public function getLoginPageOptions($parameters=false) + { + global $conf, $langs; + + if (is_array($parameters) && ! empty($parameters)) + { + foreach($parameters as $key => $value) + { + $$key=$value; + } + } + + // Entity combobox + if (empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)) + { + if (empty($entity)) $entity=1; + $lastentity=(! empty($conf->global->MULTICOMPANY_FORCE_ENTITY)?$conf->global->MULTICOMPANY_FORCE_ENTITY:$entity); + $currentcontext = explode(':', $parameters['context']); + + if (in_array('cashdeskloginpage', $currentcontext)) + { + $select_entity = $this->select_entities($lastentity, 'entity', ' tabindex="3"', true, false, false, false, '', 'minwidth100imp'); + + $tableformat = ''; + $tableformat.= ''.$langs->trans("Entity").''; + $tableformat.= ''.$select_entity.''; + $tableformat.= ''; + + $this->resprints = $tableformat; + } + else + { + $select_entity = $this->select_entities($lastentity, 'entity', ' tabindex="3"', true, false, false, false, '', 'login-entity minwidth180'); + + $divformat = "\n".'
'."\n"; + $divformat.= '
'."\n"; + $divformat.= ''.$select_entity.''."\n"; + $divformat.= '
'; + + if (! empty($conf->global->MULTICOMPANY_LOGIN_LOGO_BY_ENTITY)) { + $divformat.= ' + '; + } + + $this->resprints = $divformat; + } + } + + return 0; + } + + /** + * + */ + public function getPasswordForgottenPageOptions($parameters=false) + { + return $this->getLoginPageOptions($parameters); + } + + /** + * Add all entities default dictionnaries in database + */ + public function addAllEntitiesDefaultDicts() + { + if (! empty($this->sharingdicts)) + { + $this->getInstanceDao(); + $this->dao->getEntities(); + + $dir = "/multicompany/sql/dict/"; + + foreach($this->sharingdicts as $dict => $data) + { + // Load sql init_new_entity_dict.sql file + $file = 'init_new_entity_'.$dict.'.sql'; + $fullpath = dol_buildpath($dir.$file); + + if (file_exists($fullpath)) + { + foreach ($this->dao->entities as $entity) + { + if ($entity->id == 1) continue; + + $result=run_sql($fullpath,1,$entity->id); + } + } + } + } + } + + /** + * Load shared elements + * + * @return void + */ + private function loadSharedElements() + { + global $conf; + + if (! empty($this->sharings)) + { + $this->getInstanceDao(); + + foreach($this->sharings as $element => $ids) + { + $modulesharingenabled = 'MULTICOMPANY_'.strtoupper($element).'_SHARING_ENABLED'; + + $module = ((isset($this->sharingmodulename[$element]) && !empty($this->sharingmodulename[$element])) ? $this->sharingmodulename[$element] : $element); + + if (! empty($conf->$module->enabled) && ! empty($conf->global->$modulesharingenabled)) + { + $entities=array(); + + if (! empty($this->referent)) + { + // Load configuration of referent entity + $this->config = $this->dao->getEntityConfig($this->referent); + $this->setConstant($conf, $element); + } + + if (! empty($ids)) + { + foreach ($ids as $id) + { + $ret=$this->dao->fetch($id); + if ($ret > 0 && $this->dao->active) + { + $entities[] = $id; + } + } + + $this->entities[$element] = (! empty($entities) ? implode(",", $entities) : 0); + $this->entities[$element].= ','.$conf->entity; + } + } + } + } + //var_dump($this->entities); + } + + /** + * Get modify entity dialog + */ + private function getModifyEntityDialog($htmlname, $action, $object) + { + global $langs; + + $langs->loadLangs(array('errors','multicompany@multicompany')); + + $selectEntities = $this->select_entities('', 'entity' . $htmlname, '', false, array($object->entity)); + + $out = ''; + + if (! empty($selectEntities)) { + + $out.= ''; + + $out.= ' + '; + + $out.= '
'."\n"; + $out.= '

' . img_warning() . ' ' . $langs->trans(ucfirst($htmlname) . 'ModifyEntityDescription') . '

'."\n"; + $out.= '
' . $langs->trans('SelectAnEntity'); + $out.= $selectEntities . '
'."\n"; + $out.= '
'."\n"; + + $out.= ''; + } + + return $out; + } + + /** + * Show entity info + */ + private function getTopRightMenu() + { + global $conf, $user, $langs; + + $langs->loadLangs(array('languages','admin','multicompany@multicompany')); + + $out=''; + + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) || ! empty($user->admin)) + { + if (($conf->global->MAIN_THEME === 'eldy' && empty($conf->global->MULTICOMPANY_DROPDOWN_MENU_DISABLED) && ! GETPOSTISSET('theme')) || (GETPOSTISSET('theme') && GETPOST('theme', 'aZ', 1) === 'eldy')) + { + $out.= $this->getDropdownMenu(); + } + else + { + $form=new Form($this->db); + + $this->getInfo($conf->entity); + + $selectEntities = $this->select_entities('', 'changeentity', '', false, array($conf->entity), false, false, '', 'minwidth200imp', true, true); + + $text =''; + if (($conf->global->MAIN_THEME === 'eldy' && empty($conf->global->MULTICOMPANY_NO_TOP_MENU_ENTITY_LABEL) && ! GETPOSTISSET('theme')) || (GETPOSTISSET('theme') && GETPOST('theme', 'aZ', 1) === 'eldy')) { + $text.= ''.$this->label.''; + } + $text.= ''; + + if ($cache = getCache('country_' . $this->country_id)) { + $country = $cache; + } else { + $country = getCountry($this->country_id); + setCache('country_' . $this->country_id, $country); + } + $imgCountry=picto_from_langcode($this->country_code, 'class="multicompany-flag-country"'); + $imgLang=picto_from_langcode($this->language_code, 'class="multicompany-flag-language"'); + + $htmltext =''.$langs->trans("Entity").''."\n"; + $htmltext.= '
'; + $htmltext.='
'.$langs->trans("Label").': '.$this->label."\n"; + $htmltext.='
'.$langs->trans("Country").': '. ($imgCountry?$imgCountry.' ':'') . $country."\n"; + $htmltext.='
'.$langs->trans("Currency").': '. currency_name($this->currency_code) . ' (' . $langs->getCurrencySymbol($this->currency_code) . ')'."\n"; + $htmltext.='
'.$langs->trans("Language").': '. ($imgLang?$imgLang.' ':'') . ($this->language_code=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$this->language_code)); + if (! empty($this->description)) $htmltext.='
'.$langs->trans("Description").': '.$this->description."\n"; + $htmltext.= '

'; + + $out.= $form->textwithtooltip('', $htmltext, 2, 1, $text, 'login_block_elem multicompany_block', 2); + + if (! empty($selectEntities)) { + $out.= ' + '; + + $out.= '
'."\n"; + $out.= '
'.$langs->trans('SelectAnEntity'); + $out.= $selectEntities; + $out.= '
'."\n"; + } else { + + } + } + } + + if (($level = checkMultiCompanyVersion()) === -2) + { + $msg = get_htmloutput_mesg(img_warning('default') . ' ' . $langs->trans("MultiCompanyUpgradeIsNeeded"), '', 'mc-upgrade-alert', 1); + $out.= ' + '; + } + + $this->resprints = $out; + } + + /** + * + * @return string + */ + private function getDropdownMenu() + { + global $conf, $user, $langs; + + $this->getInfo($conf->entity); + + if ($cache = getCache('country_' . $this->country_id)) { + $country = $cache; + } else { + $country = getCountry($this->country_id); + setCache('country_' . $this->country_id, $country); + } + $imgCountry=picto_from_langcode($this->country_code, 'class="multicompany-flag-country"'); + $imgLang=picto_from_langcode($this->language_code, 'class="multicompany-flag-language"'); + + $dropdownBody = ''; + $dropdownBody.= ' '.$langs->trans("ShowMoreInfos").''; + $dropdownBody.= '
'; + $dropdownBody.= '
'.$langs->trans("Entity").''."\n"; + $dropdownBody.= '
'.$langs->trans("Label").': '.$this->label."\n"; + $dropdownBody.= '
'.$langs->trans("Country").': '. ($imgCountry?$imgCountry.' ':'') . $country."\n"; + $dropdownBody.= '
'.$langs->trans("Currency").': '. currency_name($this->currency_code) . ' (' . $langs->getCurrencySymbol($this->currency_code) . ')'."\n"; + $dropdownBody.= '
'.$langs->trans("Language").': '. ($imgLang?$imgLang.' ':'') . ($this->language_code=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$this->language_code)); + if (! empty($this->description)) $dropdownBody.= '
'.$langs->trans("Description").': '.$this->description."\n"; + $dropdownBody.= '
'; + + $selectEntities = $this->select_entities('', 'changeentity', '', false, array($conf->entity), false, false, '', 'minwidth200imp', true, true); + + $entitySwitchLink ='
'.$langs->trans("SwitchEntity").'
'; + $entityConfigLink =' '.$langs->trans("Setup").''; + + $out = '
'; + $out.= '
'; + + $out.= ' + '; + + return $out; + } + + /** + * Set parameters with referent entity + * + * @param Conf $conf + * @param string $element + */ + public function setConstant(&$conf, $element) + { + if (! empty($this->config)) + { + $constants=array(); + + if ($element == 'thirdparty') + { + $constants = array( + 'SOCIETE_CODECLIENT_ADDON', + 'COMPANY_ELEPHANT_MASK_CUSTOMER', + 'COMPANY_ELEPHANT_MASK_SUPPLIER', + 'SOCIETE_IDPROF1_UNIQUE', + 'SOCIETE_IDPROF2_UNIQUE', + 'SOCIETE_IDPROF3_UNIQUE', + 'SOCIETE_IDPROF4_UNIQUE' + ); + } + + if (! empty($constants)) + { + foreach($constants as $name) + { + if (! empty($this->config[$name])) $conf->global->$name = $this->config[$name]; + } + } + } + } + + /** + * + * @param int $groupid + * @param int $template + * @param array $entities + * @return number + */ + public function duplicateUserGroupRights($groupid, $template, $entities) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + + $error=0; + + dol_syslog(get_class($this)."::duplicateUserGroupRights groupid=".$groupid." template=".$template." entities=".implode(",", $entities), LOG_DEBUG); + + $groupstatic = new UserGroup($this->db); + $ret = $groupstatic->fetch($groupid, '', false); + if ($ret > 0) + { + $this->getInstanceDao(); + $permsgroupbyentity = $this->dao->getGroupRightsByEntity($groupid, $template); + + if (! empty($entities)) + { + foreach($entities as $entity) + { + if ($error > 0) break; + + $ret = $groupstatic->delrights('', 'allmodules', '', $entity); + if ($ret < 0) { + $error++; + break; + } + + foreach($permsgroupbyentity as $rid) + { + $ret = $groupstatic->addrights($rid, '', '', $entity); + if ($ret < 0) { + $error++; + break; + } + } + } + + if (!$error) { + return 1; + } else { + return -1; + } + + } else { + return -2; + } + + } else { + return -3; + } + } + +} diff --git a/htdocs/custom/multicompany/class/api_multicompany.class.php b/htdocs/custom/multicompany/class/api_multicompany.class.php new file mode 100755 index 00000000000..46ba5284f75 --- /dev/null +++ b/htdocs/custom/multicompany/class/api_multicompany.class.php @@ -0,0 +1,334 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use Luracast\Restler\RestException; + +dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany'); + +/** + * API class for multicompany + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class Multicompany extends DolibarrApi +{ + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'label' + ); + + /** + * Constructor + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + } + + /** + * Get properties of an entity + * + * Return an array with entity informations + * + * @param int $id ID of entity + * @return array|mixed data without useless information + * + * @throws RestException + */ + function get($id) + { + if (! DolibarrApiAccess::$user->rights->multicompany->read) { + throw new RestException(401); + } + + // The DaoMulticompany::fetch() method uses the global variable $user. + global $user; + $user = DolibarrApiAccess::$user; + + $multicompany = new DaoMulticompany($this->db); + $result = $multicompany->fetch($id); + if ( ! $result ) { + throw new RestException(404, 'entity not found'); + } + + return $this->_cleanObjectDatas($multicompany); + } + + /** + * List entities + * + * Get a list of entities + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%') and (t.visible:=:'1')" + * @return array Array of entities objects + * + * @throws RestException + */ + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + if(! DolibarrApiAccess::$user->rights->multicompany->read) { + throw new RestException(401); + } + + $sql = "SELECT t.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."entity as t"; + $sql.= ' WHERE t.active = 1'; + + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + // The DaoMulticompany::fetch() method uses the global variable $user. + global $user; + $user = DolibarrApiAccess::$user; + + $i=0; + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $multicompany= new DaoMulticompany($this->db); + if ($multicompany->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($multicompany); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve entities list : '.$db->lasterror()); + } + if ( ! count($obj_ret)) { + throw new RestException(404, 'No entities found'); + } + + return $obj_ret; + } + + /** + * Create entity object + * + * @param array $request_data Request data + * @return int ID of entity + */ + /*function post($request_data = null) + { + if (! DolibarrApiAccess::$user->rights->adherent->configurer) { + throw new RestException(401); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + $membertype = new AdherentType($this->db); + foreach($request_data as $field => $value) { + $membertype->$field = $value; + } + if ($membertype->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, 'Error creating member type', array_merge(array($membertype->error), $membertype->errors)); + } + return $membertype->id; + }*/ + + /** + * Update entity + * + * @param int $id ID of entity to update + * @param array $request_data Datas + * @return int + */ + /*function put($id, $request_data = null) + { + if (! DolibarrApiAccess::$user->rights->adherent->configurer) { + throw new RestException(401); + } + + $membertype = new AdherentType($this->db); + $result = $membertype->fetch($id); + if( ! $result ) { + throw new RestException(404, 'member type not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('member',$membertype->id,'adherent_type')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach($request_data as $field => $value) { + if ($field == 'id') continue; + // Process the status separately because it must be updated using + // the validate() and resiliate() methods of the class AdherentType. + $membertype->$field = $value; + } + + // If there is no error, update() returns the number of affected rows + // so if the update is a no op, the return value is zero. + if ($membertype->update(DolibarrApiAccess::$user) >= 0) + return $this->get($id); + + return false; + }*/ + + /** + * Delete entity + * + * @param int $id entity ID + * @return array + */ + /*function delete($id) + { + if (! DolibarrApiAccess::$user->rights->adherent->configurer) { + throw new RestException(401); + } + $membertype = new AdherentType($this->db); + $result = $membertype->fetch($id); + if( ! $result ) { + throw new RestException(404, 'member type not found'); + } + + if ( ! DolibarrApi::_checkAccessToResource('member',$membertype->id,'adherent_type')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (! $membertype->delete($membertype->id)) { + throw new RestException(401,'error when deleting member type'); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'member type deleted' + ) + ); + }*/ + + /** + * Validate fields before creating an object + * + * @param array|null $data Data to validate + * @return array + * + * @throws RestException + */ + function _validate($data) + { + $membertype = array(); + foreach (MembersTypes::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $membertype[$field] = $data[$field]; + } + return $membertype; + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + // Remove constants + foreach($object as $key => $value) + { + if (preg_match('/^MAIN_/', $key)) + { + unset($object->$key); + } + } + + unset($object->language); + unset($object->fk_tables); + unset($object->import_key); + unset($object->array_options); + unset($object->linkedObjectsIds); + unset($object->context); + unset($object->canvas); + unset($object->fk_project); + unset($object->contact); + unset($object->contact_id); + unset($object->thirdparty); + unset($object->user); + unset($object->origin); + unset($object->origin_id); + unset($object->ref_ext); + unset($object->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + unset($object->mode_reglement_id); + unset($object->cond_reglement_id); + unset($object->cond_reglement); + unset($object->fk_delivery_address); + unset($object->shipping_method_id); + unset($object->modelpdf); + unset($object->fk_account); + unset($object->note_public); + unset($object->note_private); + unset($object->fk_incoterms); + unset($object->libelle_incoterms); + unset($object->location_incoterms); + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->civility_id); + unset($object->total_ht); + unset($object->total_tva); + unset($object->total_localtax1); + unset($object->total_localtax2); + unset($object->total_ttc); + unset($object->ref); + unset($object->statut); + unset($object->note); + + return $object; + } + +} diff --git a/htdocs/custom/multicompany/class/dao_multicompany.class.php b/htdocs/custom/multicompany/class/dao_multicompany.class.php new file mode 100755 index 00000000000..1760b43094f --- /dev/null +++ b/htdocs/custom/multicompany/class/dao_multicompany.class.php @@ -0,0 +1,990 @@ + + * Copyright (C) 2011 Herve Prot + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file htdocs/multicompany/dao_multicompany.class.php + * \ingroup multicompany + * \brief File Class multicompany + */ +require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; + +/** + * \class DaoMulticompany + * \brief Class of the module multicompany + */ +class DaoMulticompany extends CommonObject +{ + public $element = 'entity'; // !< Id that identify managed objects + public $table_element = 'entity'; // !< Name of table without prefix where object is stored + + public $id; + public $label; + public $description; + + public $options=array(); + public $options_json; + + public $entity=array(); + public $entities=array(); + + public $fk_tables=array(); + + public $visible; + public $active; + public $currency; + public $language; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db = $db; + + $this->fk_tables = array( + 'societe' => array( + 'key' => 'fk_soc', + 'childs' => array( + 'societe_address', + 'societe_commerciaux', + 'societe_log', + 'societe_prices', + 'societe_remise', + 'societe_remise_except', + 'societe_rib', + 'socpeople' + ) + ), + 'product' => array( + 'key' => 'fk_product', + 'childs' => array( + 'product_ca', + 'product_lang', + 'product_price', + 'product_stock', + 'product_fournisseur_price' => array( + 'key' => 'fk_product_fournisseur', + 'childs' => array('product_fournisseur_price_log') + ), + ) + ), + 'projet' => array( + 'key' => 'fk_projet', + 'childs' => array( + 'projet_task' => array( + 'key' => 'fk_task', + 'childs' => array('projet_task_time') + ) + ) + ) + ); + } + + /** + * Fetch entity + * + * @param int $id + * @return int + */ + public function fetch($id) + { + global $user; + + //clearCache($id); + if ($cache = getCache($id)) + { + foreach ($cache as $key => $value) + { + $this->$key = $value; + } + } + else + { + $sql = "SELECT rowid, label, description, options, visible, active"; + $sql.= " FROM ".MAIN_DB_PREFIX."entity"; + $sql.= " WHERE rowid = ".$id; + + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + $this->label = $obj->label; + $this->description = $obj->description; + $this->options = json_decode($obj->options, true); + $this->visible = $obj->visible; + $this->active = $obj->active; + + if (is_array($this->options) && ! empty($this->options) && is_array($this->options['sharings'])) + { + // for backward compatibility + if (array_key_exists('referent', $this->options['sharings'])) + { + if (empty($this->options['referent'])) + { + $this->options['referent'] = $this->options['sharings']['referent']; + } + unset($this->options['sharings']['referent']); + } + + // for backward compatibility + if (array_key_exists('societe', $this->options['sharings'])) + { + if (empty($this->options['sharings']['thirdparty'])) + { + $this->options['sharings']['thirdparty'] = $this->options['sharings']['societe']; + } + unset($this->options['sharings']['societe']); + } + + // for backward compatibility + if (array_key_exists('bank_account', $this->options['sharings'])) + { + if (empty($this->options['sharings']['bankaccount'])) + { + $this->options['sharings']['bankaccount'] = $this->options['sharings']['bank_account']; + } + unset($this->options['sharings']['bank_account']); + } + } + + $this->fetch_optionals(); + + $cache = array( + 'id' => $this->id, + 'label' => $this->label, + 'description' => $this->description, + 'options' => $this->options, + 'visible' => $this->visible, + 'active' => $this->active, + 'array_options' => $this->array_options + ); + + setCache($this->id, $cache); + } + else + { + return -2; + } + } + else + { + return -3; + } + } + + if (! empty($user->login)) + { + $this->getConstants(); + } + + return 1; + } + + /** + * Create entity + * + * @param User $user Object of user that ask creation + * @param int $call_trigger false = no, true = yes + * @return int >= 0 if OK, < 0 if KO + */ + public function create(User $user, $call_trigger = true) + { + global $conf; + + $error=0; + + // Clean parameters + $this->label = trim($this->label); + $this->description = trim($this->description); + $this->options_json = json_encode($this->options); + + dol_syslog(get_class($this)."::create ".$this->label); + + $this->db->begin(); + + $now=dol_now(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."entity ("; + $sql.= "label"; + $sql.= ", description"; + $sql.= ", datec"; + $sql.= ", fk_user_creat"; + $sql.= ", options"; + $sql.= ", visible"; + $sql.= ", active"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->escape($this->label)."'"; + $sql.= ", '".$this->db->escape($this->description)."'"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", ".$user->id; + $sql.= ", '".$this->db->escape($this->options_json)."'"; + $sql.= ", ".(! empty($this->visible)?$this->db->escape($this->visible):0); + $sql.= ", ".(! empty($this->active)?$this->db->escape($this->active):0); + $sql.= ")"; + + dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."entity"); + + if (! $error) { + + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { + $result = $this->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } + } + + dol_syslog(get_class($this)."::Create success id=".$this->id); + } + + if (!$error && $call_trigger) + { + // Call trigger + $result = $this->call_trigger('MULTICOMPANY_CREATE', $user); + if ($result < 0) $error++; + // End call triggers + } + + if (empty($error)) { + $this->db->commit(); + return $this->id; + } + else + { + dol_syslog(get_class($this)."::Create echec ".$this->error); + $this->db->rollback(); + return -1; + } + } + + /** + * Update entity + * + * @param int $id Id of entity (deprecated, use 0 here and call update on an object loaded by a fetch) + * @param User $user User who requests the update + * @param int $call_trigger false = no, true = yes + * @return int <0 if KO, >=0 if OK + */ + public function update($id, User $user, $call_trigger = true) + { + global $conf; + + $error=0; + + if (empty($id)) $id = $this->id; + + // Clean parameters + $this->label = trim($this->label); + $this->description = trim($this->description); + $this->options_json = json_encode($this->options); + + dol_syslog(get_class($this)."::update id=".$id." label=".$this->label); + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."entity SET"; + $sql.= " label = '" . $this->db->escape($this->label) ."'"; + $sql.= ", description = '" . $this->db->escape($this->description) ."'"; + $sql.= ", options = '" . $this->db->escape($this->options_json) ."'"; + $sql.= " WHERE rowid = " . $id; + + dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + dol_syslog(get_class($this)."::Update success id=".$id); + + if (! $error) { + + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { + $result = $this->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } + } + } + + if (!$error && $call_trigger) + { + // Call trigger + $result = $this->call_trigger('MULTICOMPANY_MODIFY', $user); + if ($result < 0) $error++; + // End call triggers + } + + if (empty($error)) { + $this->db->commit(); + clearCache($id); + clearCache('constants_' . $id); + return 1; + } + else + { + dol_syslog(get_class($this)."::Update echec ".$this->error, LOG_ERR); + $this->db->rollback(); + return -1; + } + } + + /** + * Delete entity + * + * @param int $id Id of entity to delete + * @param int $call_trigger false = no, true = yes + * @return int <0 if KO, >0 if OK + */ + public function delete($id, $call_trigger = true) + { + global $user; + + $error=0; + + $this->db->begin(); + + if (!$error && $call_trigger) + { + // Call trigger + $result = $this->call_trigger('MULTICOMPANY_DELETE', $user); + if ($result < 0) $error++; + // End call triggers + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE entity = " . $id; + dol_syslog(get_class($this)."::Delete sql=".$sql, LOG_DEBUG); + if ($this->db->query($sql)) + { + // TODO remove records of all tables + } + else + { + $error++; + $this->error .= $this->db->lasterror(); + dol_syslog(get_class($this)."::Delete erreur -1 ".$this->error, LOG_ERR); + } + } + + // Removed extrafields + if (!$error) + { + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error -2 ".$this->error, LOG_ERR); + } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."entity"; + $sql.= " WHERE rowid = " . $id; + dol_syslog(get_class($this)."::Delete sql=".$sql, LOG_DEBUG); + if (!$this->db->query($sql)) { + $error++; + $this->error .= $this->db->lasterror(); + dol_syslog(get_class($this)."::Delete erreur -1 ".$this->error, LOG_ERR); + } + } + + if (! $error) + { + dol_syslog(get_class($this)."::Delete success id=".$id); + $this->db->commit(); + clearCache($id); + clearCache('constants_' . $id); + return 1; + } + else + { + dol_syslog(get_class($this)."::Delete echec ".$this->error); + $this->db->rollback(); + return -1; + } + } + + /** + * + * + */ + public function getConstants() + { + $key = 'constants_' . $this->id; + //clearCache('constants_' . $this->id); + + if ($cache = getCache($key)) + { + foreach ($cache as $key => $value) + { + $this->$key = $value; + } + } + else + { + $cache=array(); + + $sql = "SELECT "; + $sql.= $this->db->decrypt('name')." as name"; + $sql.= ", ".$this->db->decrypt('value')." as value"; + $sql.= " FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE entity = ".$this->id; + $sql.= " AND ".$this->db->decrypt('name')." LIKE 'MAIN_%'"; + + $result = $this->db->query($sql); + if ($result) + { + $num=$this->db->num_rows($result); + $i=0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + + if ($obj->name === 'MAIN_INFO_SOCIETE_COUNTRY') + { + $tmp = explode(':', $obj->value); + $this->country_id = $tmp[0]; + $cache['country_id'] = $this->country_id; + $this->country_code = $tmp[1]; + $cache['country_code'] = $this->country_code; + } + else if ($obj->name === 'MAIN_MONNAIE') + { + $this->currency_code = $obj->value; + $cache['currency_code'] = $this->currency_code; + } + else if ($obj->name === 'MAIN_LANG_DEFAULT') + { + $this->language_code = $obj->value; + $cache['language_code'] = $this->language_code; + } + else if ($obj->name === 'MAIN_INFO_SOCIETE_NOM') + { + $this->name = $obj->value; + $cache['name'] = $this->name; + } + else if ($obj->name === 'MAIN_INFO_SOCIETE_ZIP') + { + $this->zip = $obj->value; + $cache['zip'] = $this->zip; + } + else if ($obj->name === 'MAIN_INFO_SOCIETE_ADDRESS') + { + $this->address = $obj->value; + $cache['address'] = $this->address; + } + else if ($obj->name === 'MAIN_INFO_SOCIETE_TOWN') + { + $this->town = $obj->value; + $cache['town'] = $this->town; + } + else if ($obj->name === 'MAIN_INFO_SOCIETE_STATE') + { + $this->state_id = $obj->value; + $cache['state_id'] = $this->state_id; + } + + $constname = $obj->name; + $this->$constname = $obj->value; + $cache[$constname] = $this->$constname; + + $i++; + } + + setCache($key, $cache); + } + else + { + return -1; + } + } + + return 1; + } + + /** + * Remove all records of an entity + * + * @param int $id Entity id + * @return int + */ + private function deleteEntityRecords($id) + { + $error=1; + + $this->db->begin(); + + $tables = $this->db->DDLListTables($this->db->database_name); + if (is_array($tables) && ! empty($tables)) + { + foreach($tables as $table) + { + $fields = $this->db->DDLInfoTable($table); + foreach ($fields as $field) + { + if (is_array($field) && in_array('entity', $field)) + { + $tablewithoutprefix = str_replace(MAIN_DB_PREFIX, '', $table); + $objIds = $this->getIdByForeignKey($tablewithoutprefix, $id); + if (! empty($objIds)) + { + if (array_key_exists($tablewithoutprefix, $this->fk_tables)) + { + // Level 0 + $foreignKey = $this->fk_tables[$tablewithoutprefix]['key']; + foreach($this->fk_tables[$tablewithoutprefix]['childs'] as $childTable => $child) + { + // Level 1 + if (! is_int($childTable) && is_array($child)) + { + echo 'childTableLevel1='.$childTable.'
'; + $objLevel1Ids = array(); + foreach($objIds as $rowid) + { + $ret = $this->getIdByForeignKey($childTable, $rowid, $foreignKey); + if (!empty($ret)) + $objLevel1Ids = array_merge($objLevel1Ids, $ret); + } + + sort($objLevel1Ids); + //var_dump($objLevel1Ids); + + // Level 2 + foreach($child['childs'] as $childLevel2) + { + echo 'childTableLevel2='.$childLevel2.'
'; + foreach($objLevel1Ids as $rowid) + { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $childLevel2; + $sql.= " WHERE " . $child['key'] . " = " . $rowid; + //echo $sql.'
'; + //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG); + /*if (!$this->db->query($sql)) { + $error++; + $this->error .= $this->db->lasterror(); + dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR); + }*/ + } + } + + foreach($objIds as $rowid) + { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $childTable; + $sql.= " WHERE " . $foreignKey . " = " . $rowid; + //echo $sql.'
'; + //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG); + /*if (!$this->db->query($sql)) { + $error++; + $this->error .= $this->db->lasterror(); + dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR); + }*/ + } + } + else + { + foreach($objIds as $rowid) + { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $child; + $sql.= " WHERE " . $foreignKey . " = " . $rowid; + //echo $sql.'
'; + //dol_syslog(get_class($this)."::deleteEntityRecords sql=" . $sql, LOG_DEBUG); + /*if (!$this->db->query($sql)) { + $error++; + $this->error .= $this->db->lasterror(); + dol_syslog(get_class($this)."::deleteEntityRecords error -1 " . $this->error, LOG_ERR); + }*/ + } + } + } + echo 'with childs = '.$table.'
'; + } + else + { + echo 'without childs = '.$table.'
'; + } + } + } + } + } + + if (! $error) + { + dol_syslog(get_class($this)."::deleteEntityRecords success entity=".$id); + $this->db->commit(); + return 1; + } + else + { + dol_syslog(get_class($this)."::deleteEntityRecords echec ".$this->error); + $this->db->rollback(); + return -1; + } + } + return 0; + } + + /** + * Get all rowid from a table by couple foreign key / id + * + * @param string $table + * @param int $id + * @param string $foreignkey + * @param string $fieldname + * @return int[] + */ + private function getIdByForeignKey($table, $id, $foreignkey = 'entity', $fieldname = 'rowid') + { + $objIds=array(); + $foreignkey = (! empty($foreignkey) ? $foreignkey : 'entity'); + $fieldname = (! empty($fieldname) ? $fieldname : 'rowid'); + + $sql = "SELECT " . $fieldname . " FROM " . MAIN_DB_PREFIX . $table; + $sql.= " WHERE " . $foreignkey . " = " . $id; + //echo $sql.'
'; + $resql = $this->db->query($sql); + if ($resql) + { + $i = 0; + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $objIds[] = $obj->$fieldname; + $i++; + } + } + + return $objIds; + } + + /** + * Set status of an entity + * + * @param int $id Id of entity + * @param string $type Type of status (visible or active) + * @param string $value Value of status (0: disable, 1: enable) + * @return int + */ + public function setEntity($id, $type='active', $value) + { + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."entity"; + $sql.= " SET " . $this->db->escape($type) . " = " . (int) $value; + $sql.= " WHERE rowid = " . (int) $id; + + dol_syslog(get_class($this)."::setEntity sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->db->commit(); + clearCache($id); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * List of entities + * + * @param int $login If use in login page or not + * @param array $exclude Entity ids to exclude + * @param bool $onlyactive sort only active entities + * @return void + */ + public function getEntities($login = false, $exclude = false, $onlyactive = false) + { + global $conf, $user; + + $this->entities=array(); + + if ($login || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) || (! empty($user->admin) && empty($user->entity))) + { + $sql = "SELECT DISTINCT(rowid), rang"; // Distinct parce que si user dans plusieurs groupes d'une entité, la liste d'entités de la petite terre affiche plusieurs fois la même entité + $sql.= " FROM ".MAIN_DB_PREFIX."entity"; + if (! empty($user->admin) && empty($user->entity) && is_array($exclude) && ! empty($exclude)) + { + $exclude = implode(",", $exclude); + $sql.= " WHERE rowid NOT IN (" . $exclude .")"; + if (! empty($onlyactive)) $sql.= " AND active = 1"; + } + else if (! empty($onlyactive)) { + $sql.= " WHERE active = 1"; + } + if (!$login) { + $sql.= " ORDER BY rowid"; + } + else { + $sql.= " ORDER BY rang DESC, rowid ASC"; + } + } + else + { + $sql = "SELECT DISTINCT(entity) as rowid"; // Distinct parce que si user dans plusieurs groupes d'une entité, la liste d'entités de la petite terre affiche plusieurs fois la même entité + $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_user"; + $sql.= " WHERE fk_user = ".$user->id; + $sql.= " ORDER BY entity"; + } + + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + + $objectstatic = new self($this->db); + $ret = $objectstatic->fetch($obj->rowid); + + $this->entities[$i] = $objectstatic; + + $i++; + } + } + } + + /** + * Check user $userid belongs to at least one group created into entity $id + * + * @param int $entity + * @param int $userid + * @return int + */ + public function verifyRight($entity, $userid) + { + global $conf; + + $tmpuser=new User($this->db); + $tmpuser->fetch($userid); + //$tmpuser->fetch($userid, '', '',0, $entity); // TODO check compatibility with DAV authentication + + if ($tmpuser->id) + { + if (empty($tmpuser->entity)) return 1; // superadmin always allowed + if ($tmpuser->entity == $entity && $tmpuser->admin) return 1; // entity admin allowed + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + if ($tmpuser->entity == $entity) return 1; // user allowed if belong to entity + } + else + { + $sql = "SELECT count(rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."usergroup_user"; + $sql.= " WHERE fk_user=".$userid; + $sql.= " AND entity=".$entity; + //echo $sql; + + dol_syslog(get_class($this)."::verifyRight sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + return $obj->nb; // user allowed if at least in one group + } + } + } + + return 0; + } + + /** + * Get constants values of an entity + * + * @param int $entity Entity id + * @param string $constname Specific contant + * @return array Array of constants + */ + public function getEntityConfig($entity, $constname=null) + { + $const=array(); + + $sql = "SELECT ".$this->db->decrypt('value')." as value"; + $sql.= ", ".$this->db->decrypt('name')." as name"; + $sql.= " FROM ".MAIN_DB_PREFIX."const"; + $sql.= " WHERE entity = " . $entity; + if (! empty($constname)) { + if (preg_match('/\_\*$/', $constname)) + { + $constname = str_replace('*', '', $constname); + $sql.= " AND ".$this->db->decrypt('name')." LIKE '" . $this->db->escape($constname) ."%'"; + } + else + { + $sql.= " AND ".$this->db->decrypt('name')." = '" . $this->db->escape($constname) ."'"; + } + } + + dol_syslog(get_class($this)."::getEntityConfig sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $i = 0; + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $const[$obj->name] = $obj->value; + + $i++; + } + + } + return $const; + } + + /** + * Get group rights by entity + * + * @param int $group + * @param int $entity + * @return array[] + */ + public function getGroupRightsByEntity($group, $entity) + { + $permsgroupbyentity = array(); + + $sql = "SELECT DISTINCT r.id, r.libelle, r.module, gr.entity"; + $sql.= " FROM ".MAIN_DB_PREFIX."rights_def as r,"; + $sql.= " ".MAIN_DB_PREFIX."usergroup_rights as gr"; + $sql.= " WHERE gr.fk_id = r.id"; + $sql.= " AND gr.entity = " . (int) $entity; + $sql.= " AND gr.fk_usergroup = " . (int) $group; + + dol_syslog(get_class($this)."::getGroupRightsByEntity sql=".$sql, LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + array_push($permsgroupbyentity, $obj->id); + $i++; + } + + $this->db->free($result); + + return $permsgroupbyentity; + } + else + { + dol_print_error($db); + } + } + + /** + * Get list of groups + * + * @return array + */ + public function getListOfGroups() + { + $ret=array(); + + $sql = "SELECT g.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."usergroup as g"; + $sql.= " GROUP BY g.rowid"; + + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + $ret[] = $obj->rowid; + } + + $this->db->free($result); + + return $ret; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * + * @param unknown $groupid + * @param unknown $template + * @return User[]|number + */ + public function getListOfUsersInGroupByTemplate($groupid, $template) + { + $ret=array(); + + $sql = "SELECT u.rowid, ug.entity as usergroup_entity"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; + $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql.= " WHERE ug.fk_user = u.rowid"; + $sql.= " AND ug.fk_usergroup = " . (int) $groupid; + $sql.= " AND ug.entity = " . (int) $template; + + dol_syslog(get_class($this)."::getListOfUsersInGroupByEntity groupid=".$groupid." template=".$template, LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + if (! array_key_exists($obj->rowid, $ret)) + { + $newuser=new User($this->db); + $newuser->fetch($obj->rowid); + $ret[$obj->rowid]=$newuser; + } + } + + $this->db->free($resql); + + return $ret; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + +} diff --git a/htdocs/custom/multicompany/class/index.html b/htdocs/custom/multicompany/class/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/class/ssp.class.php b/htdocs/custom/multicompany/class/ssp.class.php new file mode 100755 index 00000000000..d048ea745ca --- /dev/null +++ b/htdocs/custom/multicompany/class/ssp.class.php @@ -0,0 +1,412 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file /multicompany/class/ssp.class.php + * \ingroup multicompany + * \brief File of class to manage DataTables server-side processing + */ + +/** + * \class SSP + * \brief DataTables server-side processing class + */ +class SSP +{ + /** + * Create the data output array for the DataTables rows + * + * @param array $columns Column information array + * @param array $data Data from the SQL get + * @return array Formatted data in a row based format + */ + static function data_output ( $columns, $data ) + { + $out = array(); + + for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) { + $row = array(); + + for ( $j=0, $jen=count($columns) ; $j<$jen ; $j++ ) { + $column = $columns[$j]; + + // Is there a formatter? + if ( isset( $column['formatter'] ) ) { + $row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] ); + } + else { + $row[ $column['dt'] ] = $data[$i][ $columns[$j]['db'] ]; + } + } + + $out[] = $row; + } + + return $out; + } + + + /** + * Paging + * + * Construct the LIMIT clause for server-side processing SQL query + * + * @param array $request Data sent to server by DataTables + * @param array $columns Column information array + * @return string SQL limit clause + */ + static function limit ( $request, $columns, $db ) + { + $limit = ''; + + if ( isset($request['start']) && $request['length'] != -1 ) { + $limit = $db->plimit(intval($request['length']), intval($request['start'])); + } + + return $limit; + } + + + /** + * Ordering + * + * Construct the ORDER BY clause for server-side processing SQL query + * + * @param array $request Data sent to server by DataTables + * @param array $columns Column information array + * @return string SQL order by clause + */ + static function order ( $request, $columns, $db ) + { + $order = ''; + $sortfield = array(); + $sortorder = array(); + + if ( isset($request['order']) && count($request['order']) ) { + $dtColumns = self::pluck( $columns, 'dt' ); + for ( $i=0, $ien=count($request['order']) ; $i<$ien ; $i++ ) { + // Convert the column index into the column data property + $columnIdx = intval($request['order'][$i]['column']); + $requestColumn = $request['columns'][$columnIdx]; + + $columnIdx = array_search( $requestColumn['data'], $dtColumns ); + $column = $columns[ $columnIdx ]; + + if ( $requestColumn['orderable'] == 'true' ) { + $dir = $request['order'][$i]['dir'] === 'asc' ? 'ASC' : 'DESC'; + $sortfield[] = $column['db']; + $sortorder[] = $dir; + } + } + + $order = $db->order(implode(', ', $sortfield), implode(', ', $sortorder)); + } + + return $order; + } + + + /** + * Searching / Filtering + * + * Construct the WHERE clause for server-side processing SQL query. + * + * NOTE this does not match the built-in DataTables filtering which does it + * word by word on any field. It's possible to do here performance on large + * databases would be very poor + * + * @param array $request Data sent to server by DataTables + * @param array $columns Column information array + * @param array $bindings Array of values for PDO bindings, used in the + * sql_exec() function + * @return string SQL where clause + */ + static function filter ( $request, $columns, $db ) + { + $globalSearch = array(); + $columnSearch = array(); + $dtColumns = self::pluck( $columns, 'dt' ); + + if ( isset($request['search']) && $request['search']['value'] != '' ) { + $str = $request['search']['value']; + + for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) { + $requestColumn = $request['columns'][$i]; + $columnIdx = array_search( $requestColumn['data'], $dtColumns ); + $column = $columns[ $columnIdx ]; + + if ( $requestColumn['searchable'] == 'true' ) { + $globalSearch[] = $column['db']." LIKE '%" . $db->escape($str)."%'"; + } + } + } + + // Individual column filtering + if ( isset( $request['columns'] ) ) { + for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) { + $requestColumn = $request['columns'][$i]; + $columnIdx = array_search( $requestColumn['data'], $dtColumns ); + $column = $columns[ $columnIdx ]; + + $str = $requestColumn['search']['value']; + + if ( $requestColumn['searchable'] == 'true' && + $str != '' ) { + $columnSearch[] = $column['db']." LIKE '%" . $db->escape($str)."%'"; + } + } + } + + // Combine the filters into a single string + $where = ''; + + if ( count( $globalSearch ) ) { + $where = '('.implode(' OR ', $globalSearch).')'; + } + + if ( count( $columnSearch ) ) { + $where = $where === '' ? + implode(' AND ', $columnSearch) : + $where .' AND '. implode(' AND ', $columnSearch); + } + + if ( $where !== '' ) { + $where = 'WHERE '.$where; + } + + return $where; + } + + + /** + * Perform the SQL queries needed for an server-side processing requested, + * utilising the helper functions of this class, limit(), order() and + * filter() among others. The returned array is ready to be encoded as JSON + * in response to an SSP request, or can be modified if needed before + * sending back to the client. + * + * @param array $request Data sent to server by DataTables + * @param string $table SQL table to query + * @param string $primaryKey Primary key of the table + * @param array $columns Column information array + * @return array Server-side processing response array + */ + static function simple ( $request, $db, $table, $primaryKey, $columns ) + { + // Build the SQL query string from the request + $limit = self::limit( $request, $columns, $db ); + $order = self::order( $request, $columns, $db ); + $where = self::filter( $request, $columns, $db ); + + // Main query to actually get the data + $sql = + "SELECT ".implode(", ", self::pluck($columns, 'db'))." + FROM $table + $where + $order + $limit"; + + $data = self::sql_exec($db, $sql); + //print_r($data); + + // Data set length after filtering + $resFilterLength = self::sql_exec($db, + "SELECT COUNT({$primaryKey}) + FROM $table + $where" + ); + $recordsFiltered = $resFilterLength[0][0]; + + // Total data set length + $resTotalLength = self::sql_exec($db, + "SELECT COUNT({$primaryKey}) + FROM $table" + ); + $recordsTotal = $resTotalLength[0][0]; + + /* + * Output + */ + return array( + "draw" => isset ( $request['draw'] ) ? + intval( $request['draw'] ) : + 0, + "recordsTotal" => intval( $recordsTotal ), + "recordsFiltered" => intval( $recordsFiltered ), + "data" => self::data_output( $columns, $data ) + ); + } + + + /** + * The difference between this method and the `simple` one, is that you can + * apply additional `where` conditions to the SQL queries. These can be in + * one of two forms: + * + * * 'Result condition' - This is applied to the result set, but not the + * overall paging information query - i.e. it will not effect the number + * of records that a user sees they can have access to. This should be + * used when you want apply a filtering condition that the user has sent. + * * 'All condition' - This is applied to all queries that are made and + * reduces the number of records that the user can access. This should be + * used in conditions where you don't want the user to ever have access to + * particular records (for example, restricting by a login id). + * + * @param array $request Data sent to server by DataTables + * @param string $table SQL table to query + * @param string $primaryKey Primary key of the table + * @param array $columns Column information array + * @param string $whereResult WHERE condition to apply to the result set + * @param string $whereAll WHERE condition to apply to all queries + * @return array Server-side processing response array + */ + static function complex ( $request, $db, $table, $primaryKey, $columns, $whereResult=null, $whereAll=null ) + { + $whereAllSql = ''; + + // Build the SQL query string from the request + $limit = self::limit( $request, $columns, $db ); + $order = self::order( $request, $columns, $db ); + $where = self::filter( $request, $columns, $db ); + + $whereResult = self::_flatten( $whereResult ); + $whereAll = self::_flatten( $whereAll ); + + if ( $whereResult ) { + $where = $where ? + $where .' AND '.$whereResult : + 'WHERE '.$whereResult; + } + + if ( $whereAll ) { + $where = $where ? + $where .' AND '.$whereAll : + 'WHERE '.$whereAll; + + $whereAllSql = 'WHERE '.$whereAll; + } + + // Main query to actually get the data + $data = self::sql_exec($db, + "SELECT ".implode(", ", self::pluck($columns, 'db'))." + FROM $table + $where + $order + $limit" + ); + + // Data set length after filtering + $resFilterLength = self::sql_exec($db, + "SELECT COUNT({$primaryKey}) + FROM $table + $where" + ); + $recordsFiltered = $resFilterLength[0][0]; + + // Total data set length + $resTotalLength = self::sql_exec($db, + "SELECT COUNT({$primaryKey}) + FROM $table ". + $whereAllSql + ); + $recordsTotal = $resTotalLength[0][0]; + + /* + * Output + */ + return array( + "draw" => isset ( $request['draw'] ) ? + intval( $request['draw'] ) : + 0, + "recordsTotal" => intval( $recordsTotal ), + "recordsFiltered" => intval( $recordsFiltered ), + "data" => self::data_output( $columns, $data ) + ); + } + + + /** + * Execute an SQL query on the database + * + * @param string $sql SQL query to execute. + * @return array Result from the query (all rows) + */ + static function sql_exec ( $db, $sql ) + { + $out=array(); + + $resql = $db->query($sql); + if ($resql) + { + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($out, $array); + $i++; + } + } + + return $out; + } + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Internal methods + */ + + /** + * Pull a particular property from each assoc. array in a numeric array, + * returning and array of the property values from each item. + * + * @param array $a Array to get data from + * @param string $prop Property to read + * @return array Array of property values + */ + static function pluck ( $a, $prop ) + { + $out = array(); + + for ( $i=0, $len=count($a) ; $i<$len ; $i++ ) { + $out[] = $a[$i][$prop]; + } + + return $out; + } + + + /** + * Return a string from an array or a string + * + * @param array|string $a Array to join + * @param string $join Glue for the concatenation + * @return string Joined string + */ + static function _flatten ( $a, $join = ' AND ' ) + { + if ( ! $a ) { + return ''; + } + else if ( $a && is_array($a) ) { + return implode( $join, $a ); + } + return $a; + } +} + diff --git a/htdocs/custom/multicompany/core/ajax/functions.php b/htdocs/custom/multicompany/core/ajax/functions.php new file mode 100755 index 00000000000..335d84fc154 --- /dev/null +++ b/htdocs/custom/multicompany/core/ajax/functions.php @@ -0,0 +1,286 @@ + + * Copyright (C) 2011 Herve Prot + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file multicompany/core/ajax/functions.php + * \brief File to return ajax result + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK',1); + +if (isset($_GET['action']) && $_GET['action'] === 'getEntityLogo') { + define("NOLOGIN",1); // This means this output page does not require to be logged. + $entity=(! empty($_GET['id']) ? (int) $_GET['id'] : 1); + if (is_numeric($entity)) define("DOLENTITY", $entity); +} + +$res=@include("../../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../../main.inc.php"); // For "custom" directory + +dol_include_once('/multicompany/class/actions_multicompany.class.php', 'ActionsMulticompany'); +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; + +$id = GETPOST('id', 'int'); // id of entity +$action = GETPOST('action', 'alpha'); // action method +$type = GETPOST('type', 'alpha'); // type of action +$element = GETPOST('element', 'alpha'); // type of element +$fk_element = GETPOST('fk_element', 'int'); // id of element + +$template = GETPOST('template', 'int'); +if (GETPOSTISSET('entities')) { + $entities = json_decode(GETPOST('entities', 'none'), true); +} + +/* + * View + */ + +// Ajout directives pour resoudre bug IE +//header('Cache-Control: Public, must-revalidate'); +//header('Pragma: public'); + +//top_htmlhead("", "", 1); // Replaced with top_httphead. An ajax page does not need html header. +top_httphead('application/json'); + +if (empty($conf->multicompany->enabled)) { + echo json_encode(array('status' => 'error')); + $db->close(); + exit(); +} + +//print ''."\n"; + +// Registering the location of boxes +if (! empty($action) && is_numeric($id)) +{ + if ($action == 'switchEntity' && ! empty($user->login)) + { + dol_syslog("multicompany action=".$action." entity=".$id, LOG_DEBUG); + + $object = new ActionsMulticompany($db); + echo $object->switchEntity($id); + } + else if ($action == 'setStatusEnable' && ! empty($user->admin) && ! $user->entity) + { + dol_syslog("multicompany action=".$action." type=".$type." entity=".$id, LOG_DEBUG); + + $object = new ActionsMulticompany($db); + $fieldname = ($type == 'activetemplate' ? 'active' : $type); + echo $object->setStatus($id, $fieldname, 1); + } + else if ($action == 'setStatusDisable' && ! empty($user->admin) && ! $user->entity) + { + dol_syslog("multicompany action=".$action." type=".$type." entity=".$id, LOG_DEBUG); + + $object = new ActionsMulticompany($db); + $fieldname = ($type == 'activetemplate' ? 'active' : $type); + $ret = $object->setStatus($id, $fieldname, 0); + if ($ret == 1 && $type == 'active') { + $ret = $object->setStatus($id, 'visible', 0); + } + echo $ret; + } + else if ($action == 'deleteEntity' && $id != 1 && ! empty($user->admin) && ! $user->entity) + { + dol_syslog("multicompany action=".$action." entity=".$id, LOG_DEBUG); + + $object = new ActionsMulticompany($db); + echo $object->deleteEntity($id); + } + else if ($action == 'setColOrder' && ! empty($user->admin) && ! $user->entity) + { + $id = (int) $id; + $direction = GETPOST('dir', 'aZ'); + $colOrder = array('id' => $id, 'direction' => $direction); + + if (dolibarr_set_const($db, 'MULTICOMPANY_COLORDER', json_encode($colOrder), 'chaine', 0, '', 0) > 0) { + $ret = json_encode(array('status' => 'success')); + } + else { + $ret = json_encode(array('status' => 'error')); + } + + echo $ret; + } + else if ($action == 'setColHidden' && ! empty($user->admin) && ! $user->entity) + { + $state = GETPOST('state', 'aZ'); + $colHidden = (! empty($conf->global->MULTICOMPANY_COLHIDDEN) ? json_decode($conf->global->MULTICOMPANY_COLHIDDEN, true) : array()); + + if ($state == 'visible') { + $colHidden = array_diff($colHidden, array(intval($id))); + } else if ($state == 'hidden') { + array_push($colHidden, intval($id)); + } + + sort($colHidden); + + if (dolibarr_set_const($db, 'MULTICOMPANY_COLHIDDEN', json_encode($colHidden), 'chaine', 0, '', 0) > 0) { + $ret = json_encode(array('status' => 'success')); + } + else { + $ret = json_encode(array('status' => 'error')); + } + + echo $ret; + } + else if ($action == 'modifyEntity' && ((! empty($user->admin) && ! $user->entity) || ! empty($user->rights->multicompany->thirdparty->write))) + { + if ($element == 'societe') + { + $object = new Societe($db); + $ret = $object->fetch($fk_element); + if ($ret > 0) { + + $object->oldcopy = clone $object; + + // To not set code if third party is not concerned. But if it had values, we keep them. + if (empty($object->client) && empty($object->oldcopy->code_client)) $object->code_client=''; + if (empty($object->fournisseur) && empty($object->oldcopy->code_fournisseur)) $object->code_fournisseur=''; + + $object->entity = $id; + + $ret = $object->update($object->id, $user, 0, $object->oldcopy->codeclient_modifiable(), $object->oldcopy->codefournisseur_modifiable(), 'update', 1); + if ($ret > 0) { + $ret = json_encode(array('status' => 'success')); + } + else { + $ret = json_encode(array('status' => 'error', 'error' => $object->errors)); + } + } + else { + $ret = json_encode(array('status' => 'error', 'error' => $object->errors)); + } + } + else if ($element == 'contact') + { + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + + $object = new Contact($db); + $ret = $object->fetch($fk_element); + if ($ret > 0) { + + $object->entity = $id; + + $ret = $object->update($object->id, $user, 1, 'update', 1); + if ($ret > 0) { + $ret = json_encode(array('status' => 'success')); + } + else { + $ret = json_encode(array('status' => 'error', 'error' => $object->errors)); + } + } + else { + $ret = json_encode(array('status' => 'error', 'error' => $object->errors)); + } + } + + echo $ret; + } + else if ($action === 'getEntityOptions' && ! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && ! empty($user->admin) && empty($user->entity)) + { + $object = new ActionsMulticompany($db); + $object->getInfo($id); + + $entities = $object->getEntitiesList(false, false, true, true); + + echo json_encode( + array( + 'status' => 'success', + 'options' => $object->options, + 'labels' => $entities + ) + ); + } + else if ($action === 'duplicateUserGroupRights' && ! empty($conf->global->MULTICOMPANY_TEMPLATE_MANAGEMENT) && ! empty($user->admin) && empty($user->entity) && ! empty($template) && ! empty($entities)) + { + $multicompany = new ActionsMulticompany($db); + $ret = $multicompany->duplicateUserGroupRights($id, $template, $entities); + if ($ret > 0) + { + echo json_encode(array('status' => 'success')); + } + else + { + echo json_encode(array( + 'status' => 'error', + 'id' => $id, + 'template' => $template, + 'entities' => $entities + ) + ); + } + } + else if ($action === 'getEntityLogo' && empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)) + { + $urllogo = DOL_URL_ROOT.'/theme/login_logo.png'; + + if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) + { + $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&entity='.$id.'&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_small); + } + elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) + { + $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&entity='.$id.'&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo); + $width = 128; + } + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) + { + $urllogo = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'; + } + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png')) + { + $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + } + + $bgimg = null; + $unsplashimg = null; + + if (! empty($conf->global->MULTICOMPANY_LOGIN_BACKGROUND_BY_ENTITY)) + { + if (! empty($conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND)) + { + $unsplashimg = $conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND; + } + + if (! empty($conf->global->MAIN_LOGIN_BACKGROUND)) + { + $bgimg = DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&entity='.$id.'&modulepart=mycompany&file=logos/'.urlencode($conf->global->MAIN_LOGIN_BACKGROUND); + } + } + + echo json_encode(array( + 'status' => 'success', + 'urllogo' => dol_html_entity_decode($urllogo, null), + 'bgimg' => dol_html_entity_decode($bgimg, null), + 'unsplashimg' => dol_html_entity_decode($unsplashimg, null) + ) + ); + } +} + +$db->close(); diff --git a/htdocs/custom/multicompany/core/ajax/index.html b/htdocs/custom/multicompany/core/ajax/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/core/ajax/list.php b/htdocs/custom/multicompany/core/ajax/list.php new file mode 100755 index 00000000000..30b48cce8bc --- /dev/null +++ b/htdocs/custom/multicompany/core/ajax/list.php @@ -0,0 +1,248 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file /multicompany/core/ajax/list.php + * \brief File to return datables output of entities list + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal +if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK',1); + +$res=@include("../../../main.inc.php"); // For root directory +if (! $res && file_exists($_SERVER['DOCUMENT_ROOT']."/main.inc.php")) + $res=@include($_SERVER['DOCUMENT_ROOT']."/main.inc.php"); // Use on dev env only +if (! $res) $res=@include("../../../../main.inc.php"); // For "custom" directory + +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; +dol_include_once('/multicompany/class/dao_multicompany.class.php', 'DaoMulticompany'); +dol_include_once('/multicompany/lib/multicompany.lib.php'); +dol_include_once('/multicompany/class/ssp.class.php'); + +$langs->loadLangs(array('languages','admin','multicompany@multicompany')); + +// Defini si peux lire/modifier permisssions +$canreadEntity=! empty($user->admin); +$caneditEntity=! empty($user->admin); +$candeleteEntity=! empty($user->admin); + +top_httphead('application/json'); + +//print ''."\n"; + +//print_r($_GET); + +if (empty($user->admin) || empty($conf->multicompany->enabled)) { + echo json_encode(array('status' => 'error')); + $db->close(); + exit(); +} + +$object = new DaoMulticompany($db); + +$extrafields = new ExtraFields($db); +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label($object->element); + +$start = array('start' => GETPOST('start', 'int')); +$length = array('length' => GETPOST('length', 'int')); +$draw = array('draw' => GETPOST('draw', 'int')); +$order = array('order' => GETPOST('order', 'array')); +$columns = array('columns' => GETPOST('columns', 'array')); +$search = array('search' => GETPOST('search', 'array')); + +$request = $start + $length + $draw + $order + $columns + $search; +//print_r($request); + +// DB table to use +$table = MAIN_DB_PREFIX . "entity"; + +// Table's primary key +$primaryKey = 'rowid'; + +// Array of database columns which should be read and sent back to DataTables. +// The `db` parameter represents the column name in the database, while the `dt` +// parameter represents the DataTables column identifier. In this case simple +// indexes +$columns = array(); + +$columns[]= array( 'db' => 'rowid', 'dt' => 'entity_id' ); +$columns[]= array( 'db' => 'label', 'dt' => 'entity_label' ); +$columns[]= array( 'db' => 'description', 'dt' => 'entity_description' ); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_name', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $object; + $object->fetch($value); + return $object->name; + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_zip', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $object; + $object->fetch($value); + return $object->zip; + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_town', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $object; + $object->fetch($value); + return $object->town; + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_country', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $object; + $object->fetch($value); + if ($cache = getCache('country_' . $object->country_id)) { + $country = $cache; + } else { + $country = getCountry($object->country_id); + setCache('country_' . $object->country_id, $country); + } + $img=picto_from_langcode($object->country_code, 'class="multicompany-flag-country"'); + return ($img?$img.' ':'') . $country; + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_currency', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $langs, $object; + $object->fetch($value); + return currency_name($object->currency_code) . ' (' . $langs->getCurrencySymbol($object->currency_code) . ')'; + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_language', + 'formatter' => function($value, $row) { + if (! empty($value)) { + global $langs, $object; + $object->fetch($value); + $img=picto_from_langcode($object->language_code, 'class="multicompany-flag-language"'); + return ($img?$img.' ':'') . ($object->language_code=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$object->language_code)); + } + } +); +if (! empty($extralabels)) { + foreach ($extralabels as $key => $name) + { + $columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_'.$key, + 'formatter' => function($value, $row) use ($key) { + global $object, $extrafields; + unset($object->array_options['options_'.$key]); // For avoid duplicate data in next row + $object->fetch_optionals(); + return $extrafields->showOutputField($key, $object->array_options['options_'.$key]); + } + ); + } +} +$columns[]= array( + 'db' => 'visible', + 'dt' => 'entity_visible', + 'formatter' => function($value, $row) { + global $langs; + if (! empty($value)) { + if ($value == 1) { + return img_picto($langs->trans("Enabled"),'on','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-visible-on'); + } else { + return ''; + } + } else if (! empty($row['active'])) { + return img_picto($langs->trans("Disabled"),'off','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-visible-off'); + } else { + return img_picto($langs->trans("Disabled"),'off','id="visible_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-disabled'); + } + } +); +$columns[]= array( + 'db' => 'active', + 'dt' => 'entity_active', + 'formatter' => function($value, $row) { + global $conf, $langs; + if ($row['rowid'] == 1 || $conf->entity == $row['rowid']) { + return img_picto($langs->trans("Enabled"),'on','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-disabled'); + } else if (! empty($value)) { + if ($row['visible'] == 2) { + return img_picto($langs->trans("Enabled"),'on','id="activetemplate_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-on'); + } else { + return img_picto($langs->trans("Enabled"),'on','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-on'); + } + } else { + if ($row['visible'] == 2) { + return img_picto($langs->trans("Disabled"),'off','id="activetemplate_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-off'); + } else { + return img_picto($langs->trans("Disabled"),'off','id="active_' . $row['rowid'] . '"',false,0,0,'','multicompany-button-active-off'); + } + } + } +); +$columns[]= array( + 'db' => 'rowid', + 'dt' => 'entity_tools', + 'formatter' => function($value, $row) { + global $conf, $langs, $caneditEntity, $candeleteEntity; + $ret=''; + if ($caneditEntity) { + $ret.= img_edit($langs->transnoentities("Edit"),0, 'id="edit_' . $value . '" class="multicompany-button-setup"'); + } + if ($candeleteEntity) { + if ($value == 1 || $conf->entity == $value) { + $ret.= img_delete($langs->transnoentities("Delete"), 'id="delete_' . $value . '" class="multicompany-button-disabled"'); + } else { + $ret.= img_delete($langs->transnoentities("Delete"), 'id="delete_' . $value . '" class="multicompany-button-delete"'); + } + } + return $ret; + } +); + +//var_dump($columns); +echo json_encode( + SSP::simple( $request, $db, $table, $primaryKey, $columns ) +); + +$db->close(); diff --git a/htdocs/custom/multicompany/core/js/index.html b/htdocs/custom/multicompany/core/js/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/core/js/lib_head.js b/htdocs/custom/multicompany/core/js/lib_head.js new file mode 100755 index 00000000000..668687e127e --- /dev/null +++ b/htdocs/custom/multicompany/core/js/lib_head.js @@ -0,0 +1,214 @@ +// Copyright (C) 2014-2019 Regis Houssin +// +// 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 +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// or see http://www.gnu.org/ + +// +// \file /multicompany/core/js/lib_head.js +// \brief File that include javascript functions (included if option use_javascript activated) +// + +/* + * + */ +function setMulticompanyConstant(url, code, input, entity) { + $.get( url, { + action: "set", + name: code, + entity: entity + }, + function() { + $("#set_" + code).hide(); + $("#del_" + code).show(); + $.each(input, function(type, data) { + // Enable another element + if (type == "enabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).removeAttr("disabled"); + }); + // Disable another element + } else if (type == "disabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).attr("disabled", true); + }); + // enable and disable another element + } else if (type == "disabledenabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).removeAttr("disabled"); + }); + // Show another element + } else if (type == "showhide" || type == "show") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).show(); + }); + } else if (type == "hideshow") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).hide(); + }); + // Set another constant + } else if (type == "set" || type == "del") { + $.each(data, function(key, value) { + if (type == "set") { + $("#set_" + value).hide(); + $("#del_" + value).show(); + $.get( url, { + action: type, + name: key, + value: value, + entity: entity + }); + } else if (type == "del") { + $("#del_" + value).hide(); + $("#set_" + value).show(); + $.get( url, { + action: type, + name: value, + entity: entity + }); + } + }); + // reload the current page + } else if (type == "reload") { + var url = window.location.pathname; + location.href=url; + } + }); + }); +} + +/* + * + */ +function delMulticompanyConstant(url, code, input, entity) { + $.get( url, { + action: "del", + name: code, + entity: entity + }, + function() { + $("#del_" + code).hide(); + $("#set_" + code).show(); + $.each(input, function(type, data) { + // Enable another element + if (type == "enabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).removeAttr("disabled"); + }); + // Disable another element + } else if (type == "disabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).attr("disabled", true); + }); + // enable and disable another element + } else if (type == "disabledenabled") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).attr("disabled", true); + }); + } else if (type == "showhide" || type == "hide") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).hide(); + }); + } else if (type == "hideshow") { + $.each(data, function(key, value) { + var newvalue=(value.search("^#") < 0 ? "#" : "") + value; + $(newvalue).show(); + }); + // Delete another constant + } else if (type == "set" || type == "del") { + $.each(data, function(key, value) { + if (type == "set") { + $("#set_" + value).hide(); + $("#del_" + value).show(); + $.get( url, { + action: type, + name: key, + value: value, + entity: entity + }); + } else if (type == "del") { + $("#del_" + value).hide(); + $("#set_" + value).show(); + $.get( url, { + action: type, + name: value, + entity: entity + }); + } + }); + // reload the current page + } else if (type == "reload") { + var url = window.location.pathname; + location.href=url; + } + }); + }); +} + +/* + * + */ +function confirmMulticompanyConstantAction(action, url, code, input, box, entity, yesButton, noButton) { + var boxConfirm = box; + $("#confirm_" + code) + .attr("title", boxConfirm.title) + .html(boxConfirm.content) + .dialog({ + resizable: false, + height: 180, + width: 500, + modal: true, + buttons: [ + { + id : 'yesButton_' + code, + text : yesButton, + click : function() { + if (action == "set") { + setMulticompanyConstant(url, code, input, entity); + } else if (action == "del") { + delMulticompanyConstant(url, code, input, entity); + } + // Close dialog + $(this).dialog("close"); + // Execute another method + if (boxConfirm.method) { + var fnName = boxConfirm.method; + if (window.hasOwnProperty(fnName)) { + window[fnName](); + } + } + } + }, + { + id : 'noButton_' + code, + text : noButton, + click : function() { + $(this).dialog("close"); + } + } + ] + }); + // For information dialog box only, hide the noButton + if (boxConfirm.info) { + $("#noButton_" + code).button().hide(); + } +} diff --git a/htdocs/custom/multicompany/core/login/functions_mc.php b/htdocs/custom/multicompany/core/login/functions_mc.php new file mode 100755 index 00000000000..69dc4d86659 --- /dev/null +++ b/htdocs/custom/multicompany/core/login/functions_mc.php @@ -0,0 +1,166 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file multicompany/core/login/functions_mc.php + * \ingroup multicompany + * \brief Authentication functions for Multicompany mode when combobox in login page is disabled + */ + + +/** + * Check validity of user/password/entity + * If test is ko, reason must be filled into $_SESSION["dol_loginmesg"] + * + * @param string $usertotest Login + * @param string $passwordtotest Password + * @param int $entitytotest Number of instance (always 1 if module multicompany not enabled) + * @return string Login if OK, '' if KO + */ +function check_user_password_mc($usertotest,$passwordtotest,$entitytotest=1) +{ + global $db,$conf,$langs; + global $mc; + + dol_syslog("functions_mc::check_user_password_mc usertotest=".$usertotest); + + $login=''; + + if (!empty($conf->multicompany->enabled)) + { + $langs->loadLangs(array('main','errors','multicompany@multicompany')); + + if (! empty($conf->global->MULTICOMPANY_HIDE_LOGIN_COMBOBOX)) + { + $entity=$entitytotest; + + if (!empty($usertotest)) + { + // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko + $table = MAIN_DB_PREFIX."user"; + $usernamecol = 'login'; + $entitycol = 'entity'; + + $sql ='SELECT rowid, entity, pass, pass_crypted'; + $sql.=' FROM '.$table; + $sql.=' WHERE '.$usernamecol." = '".$db->escape($usertotest)."'"; + $sql.=' AND statut = 1'; + + dol_syslog("functions_mc::check_user_password_mc sql=" . $sql); + $resql=$db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + if ($obj) + { + $passclear=$obj->pass; + $passcrypted=$obj->pass_crypted; + $passtyped=$passwordtotest; + + $passok=false; + + // Check crypted password + $cryptType=''; + if (! empty($conf->global->DATABASE_PWD_ENCRYPTED)) $cryptType=$conf->global->DATABASE_PWD_ENCRYPTED; + + // By default, we used MD5 + if (! in_array($cryptType,array('md5'))) $cryptType='md5'; + // Check crypted password according to crypt algorithm + if ($cryptType == 'md5') + { + if (dol_verifyHash($passtyped, $passcrypted)) + { + $passok=true; + dol_syslog("functions_mc::check_user_password_mc Authentification ok - " . $cryptType . " of pass is ok"); + } + } + + // For compatibility with old versions + if (! $passok) + { + if ((! $passcrypted || $passtyped) + && ($passclear && ($passtyped == $passclear))) + { + $passok=true; + dol_syslog("functions_mc::check_user_password_mc Authentification ok - found pass in database"); + } + } + + if ($passok && !empty($obj->entity)) + { + global $entitytotest; + + $entitytotest = $obj->entity; + + if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) + { + $sql = "SELECT uu.entity"; + $sql.= " FROM " . MAIN_DB_PREFIX . "usergroup_user as uu"; + $sql.= ", " . MAIN_DB_PREFIX . "entity as e"; + $sql.= " WHERE uu.entity = e.rowid AND e.visible < 2"; // Remove template of entity + $sql.= " AND fk_user = " . $obj->rowid; + + dol_syslog("functions_mc::check_user_password_mc sql=" . $sql, LOG_DEBUG); + $result = $db->query($sql); + if ($result) + { + while($array = $db->fetch_array($result)) // user allowed if at least in one group + { + $entitytotest = $array['entity']; + break; // stop in first entity + } + } + } + + $ret=$mc->switchEntity($entitytotest, $obj->rowid); + + if ($ret < 0) $passok=false; + } + + // Password ok ? + if ($passok) + { + $login=$usertotest; + } + else + { + dol_syslog("functions_mc::check_user_password_mc Authentification ko bad password pour '".$usertotest."'", LOG_ERR); + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword"); + } + } + else + { + dol_syslog("functions_mc::check_user_password_mc Authentification ko user not found for '".$usertotest."'", LOG_ERR); + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword"); + } + } + else + { + dol_syslog("functions_mc::check_user_password_mc Authentification ko db error for '".$usertotest."' error=".$db->lasterror(), LOG_ERR); + $_SESSION["dol_loginmesg"]=$db->lasterror(); + } + } + } + else + { + dol_syslog("functions_mc::check_user_password_mc Authentification ko, the drop-down list of entities on the login page must be hidden", LOG_ERR); + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorDropDownListOfEntitiesMustBeHidden"); + } + } + + return $login; +} diff --git a/htdocs/custom/multicompany/core/login/index.html b/htdocs/custom/multicompany/core/login/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/core/modules/index.html b/htdocs/custom/multicompany/core/modules/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php b/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php new file mode 100755 index 00000000000..6f2bd0f908c --- /dev/null +++ b/htdocs/custom/multicompany/core/modules/modMultiCompany.class.php @@ -0,0 +1,587 @@ + + * Copyright (C) 2011 Herve Prot + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \defgroup multicompany Module multicompany + * \brief Descriptor file for module multicompany + * \file htdocs/core/modules/modMultiCompany.class.php + * \ingroup multicompany + * \brief Description and activation file for module MultiCompany + */ +include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php'; + + +/** + * \class modMultiCompany + * \brief Description and activation class for module MultiCompany + */ +class modMultiCompany extends DolibarrModules +{ + /** + * Constructor. + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs; + + $this->db = $db; + + // Id for module (must be unique). + // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id). + $this->numero = 5000; + // Key text used to identify module (for permissions, menus, etc...) + $this->rights_class = 'multicompany'; + + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page + $this->family = "base"; + // Gives the possibility to the module, to provide his own family info and position of this family. + $this->familyinfo = array( + 'core' => array( + 'position' => '001', + 'label' => $langs->trans("iNodbox") + ) + ); + // Module position in the family + $this->module_position = 1; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) + $this->description = "Multi-Company Management"; + //$this->descriptionlong = "A very lon description. Can be a full HTML content"; + $this->editor_name = 'Régis Houssin'; + $this->editor_url = 'https://www.inodbox.com'; + // Can be enabled / disabled only in the main company with superadmin account + $this->core_enabled = 1; + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = '12.0.1'; + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Name of png file (without png) used for this module. + // Png file must be in theme/yourtheme/img directory under name object_pictovalue.png. + $this->picto='multicompany@multicompany'; + + // Data directories to create when module is enabled. + $this->dirs = array(); + + // Config pages. Put here list of php page names stored in admmin directory used to setup module. + $this->config_page_url = array("multicompany.php@multicompany"); + + // Defined all module parts (triggers, login, substitutions, menus, css, etc...) + $this->module_parts = array( + 'login' => array( + 'data' => 1, + 'entity' => '0' + ), + 'triggers' => array( + 'data' => 1, + 'entity' => '0' + ), + 'hooks' => array( + 'data' => array( + 'login', + 'main', + 'mainloginpage', + 'cashdeskloginpage', + 'passwordforgottenpage', + 'toprightmenu', + 'adminmodules', + 'admincompany', + 'commonobject', + 'thirdpartycard', + 'thirdpartylist', + 'customerlist', + 'prospectlist', + 'supplierlist', + 'usercard', + 'userperms', + 'groupcard', + 'groupperms', + 'userlist', + 'userhome', + 'userdao', + 'contactlist', + 'contactprospectlist', + 'contactcustomerlist', + 'contactsupplierlist', + 'contactotherlist', + 'productcard', + 'pricesuppliercard', + 'propalcard', + 'propallist', + 'ordercard', + 'orderlist', + 'invoicecard', + 'invoicelist', + 'warehousecard', + 'stocklist' + ), + 'entity' => '0' + ), + 'css' => array( + 'data' => '/multicompany/css/multicompany.css.php', + 'entity' => '0' + ) + ); + + // Dependencies + $this->depends = array(); // List of modules id that must be enabled if this module is enabled + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->phpmin = array(5,6); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(12,0,0); // Minimum version of Dolibarr required by module + $this->langfiles = array("multicompany@multicompany"); + + // Constants + // List of particular constants to add when module is enabled + $this->const=array( + 1 => array('MULTICOMPANY_MAIN_VERSION', 'chaine', $this->version, '', 0, 'multicompany', 1), + 2 => array('MULTICOMPANY_EXTERNAL_MODULES_SHARING', 'chaine', '', '', 0, 'multicompany', 0), + 3 => array('MULTICOMPANY_NO_TOP_MENU_ENTITY_LABEL', 'chaine', 1, '', 0, 'multicompany', 0) + ); + + // Boxes + $this->boxes = array(); // List of boxes + $r=0; + + // Permissions + $this->rights = array(); + $r=0; + + $r++; + $this->rights[$r][0] = 5001; + $this->rights[$r][1] = 'Read entities (For superadmin users)'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'read'; + + $r++; + $this->rights[$r][0] = 5002; + $this->rights[$r][1] = 'Create/modify entities (For superadmin users)'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'write'; + + $r++; + $this->rights[$r][0] = 5003; + $this->rights[$r][1] = 'Delete entities (For superadmin users)'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'delete'; + + // Thirdparty sharing (501x) + + $r++; + $this->rights[$r][0] = 5011; + $this->rights[$r][1] = 'Read shared third parties'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'thirdparty'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5012; + $this->rights[$r][1] = 'Create/modify shared third parties'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'thirdparty'; + $this->rights[$r][5] = 'write'; + + $r++; + $this->rights[$r][0] = 5013; + $this->rights[$r][1] = 'Delete shared third parties'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'thirdparty'; + $this->rights[$r][5] = 'delete'; + + // Contact sharing (502x) + + $r++; + $this->rights[$r][0] = 5021; + $this->rights[$r][1] = 'Read shared contacts'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'contact'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5022; + $this->rights[$r][1] = 'Create/modify shared contacts'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'contact'; + $this->rights[$r][5] = 'write'; + + $r++; + $this->rights[$r][0] = 5023; + $this->rights[$r][1] = 'Delete shared contacts'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'contact'; + $this->rights[$r][5] = 'delete'; + + // Product/service sharing (503x) + + $r++; + $this->rights[$r][0] = 5031; + $this->rights[$r][1] = 'Read shared products/services'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'product'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5032; + $this->rights[$r][1] = 'Create/modify shared products/services'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'product'; + $this->rights[$r][5] = 'write'; + + $r++; + $this->rights[$r][0] = 5033; + $this->rights[$r][1] = 'Delete shared products/services'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'product'; + $this->rights[$r][5] = 'delete'; + + // Proposal sharing (504x) + + $r++; + $this->rights[$r][0] = 5041; + $this->rights[$r][1] = 'Read shared customer proposals'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5042; + $this->rights[$r][1] = 'Create/modify shared customer proposals'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal'; + $this->rights[$r][5] = 'write'; + + $r++; + $this->rights[$r][0] = 5043; + $this->rights[$r][1] = 'Validate shared customer proposals'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal_advance'; + $this->rights[$r][5] = 'validate'; + + $r++; + $this->rights[$r][0] = 5044; + $this->rights[$r][1] = 'Send shared customer proposals'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal_advance'; + $this->rights[$r][5] = 'send'; + + $r++; + $this->rights[$r][0] = 5045; + $this->rights[$r][1] = 'Close shared customer proposals'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal'; + $this->rights[$r][5] = 'close'; + + $r++; + $this->rights[$r][0] = 5046; + $this->rights[$r][1] = 'Delete shared customer proposals'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'propal'; + $this->rights[$r][5] = 'delete'; + + // Order sharing (505x) + + $r++; + $this->rights[$r][0] = 5051; + $this->rights[$r][1] = 'Read shared customer orders'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5052; + $this->rights[$r][1] = 'Close shared customer orders'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order'; + $this->rights[$r][5] = 'write'; + + $r++; + $this->rights[$r][0] = 5054; + $this->rights[$r][1] = 'Validate shared customer orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order_advance'; + $this->rights[$r][5] = 'validate'; + + $r++; + $this->rights[$r][0] = 5056; + $this->rights[$r][1] = 'Send shared customer orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order_advance'; + $this->rights[$r][5] = 'send'; + + $r++; + $this->rights[$r][0] = 5057; + $this->rights[$r][1] = 'Close shared customer orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order'; + $this->rights[$r][5] = 'close'; + + $r++; + $this->rights[$r][0] = 5058; + $this->rights[$r][1] = 'Cancel shared customer orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order_advance'; + $this->rights[$r][5] = 'cancel'; + + $r++; + $this->rights[$r][0] = 5059; + $this->rights[$r][1] = 'Delete shared customer orders'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'order'; + $this->rights[$r][5] = 'delete'; + + // Invoice sharing (506x) + + $r++; + $this->rights[$r][0] = 5061; + $this->rights[$r][1] = 'Read shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice'; + $this->rights[$r][5] = 'read'; + + $r++; + $this->rights[$r][0] = 5062; + $this->rights[$r][1] = 'Create/modify shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice'; + $this->rights[$r][5] = 'write'; + + // There is a particular permission for unvalidate because this may be not forbidden by some laws + $r++; + $this->rights[$r][0] = 5063; + $this->rights[$r][1] = 'Devalidate shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice_advance'; + $this->rights[$r][5] = 'unvalidate'; + + $r++; + $this->rights[$r][0] = 5064; + $this->rights[$r][1] = 'Validate shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice_advance'; + $this->rights[$r][5] = 'validate'; + + $r++; + $this->rights[$r][0] = 5065; + $this->rights[$r][1] = 'Send shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice_advance'; + $this->rights[$r][5] = 'send'; + + $r++; + $this->rights[$r][0] = 5066; + $this->rights[$r][1] = 'Issue payments on shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice'; + $this->rights[$r][5] = 'payment'; + + $r++; + $this->rights[$r][0] = 5067; + $this->rights[$r][1] = 'Re-open a fully paid shared customer invoices'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice_advance'; + $this->rights[$r][5] = 'reopen'; + + $r++; + $this->rights[$r][0] = 5069; + $this->rights[$r][1] = 'Delete shared customer invoices'; + $this->rights[$r][2] = 'a'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'invoice'; + $this->rights[$r][5] = 'delete'; + + // Main menu entries + $this->menus = array(); // List of menus to add + $r=0; + + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories. + * + * @param string $options Options when enabling module ('', 'newboxdefonly', 'noboxes') + * 'noboxes' = Do not insert boxes + * 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation + * @return int 1 if OK, 0 if KO + */ + function init($options = '') + { + $sql = array(); + + $result=$this->load_tables(); + + $result=$this->setSuperAdmin(); + + $result=$this->setFirstEntity(); + + return $this->_init($sql, $options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted. + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options = '') + { + $sql = array( + "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = ".$this->db->encrypt('MAIN_MODULE_MULTICOMPANY_CSS', 1), + "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = ".$this->db->encrypt('MAIN_MODULE_MULTICOMPANY_LOGIN', 1) + ); + + return $this->_remove($sql, $options); + } + + /** + * Create tables and keys required by module + * This function is called by this->init. + * @return int <=0 if KO, >0 if OK + */ + function load_tables() + { + return $this->_load_tables('/multicompany/sql/'); + } + + /** + * Set the first entity + * + * @return int + */ + function setSuperAdmin() + { + global $user; + + $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.'user'; + $sql.= ' WHERE admin = 1 AND entity = 0'; + $res = $this->db->query($sql); + if ($res) $num = $this->db->fetch_array($res); + else dol_print_error($this->db); + + if (empty($num[0])) + { + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'user SET entity = 0'; + $sql.= ' WHERE admin = 1 AND rowid IN (1,'.$user->id.')'; + if ($this->db->query($sql)) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + return 0; + } + } + + /** + * Set the first entity + * + * @return int + */ + function setFirstEntity() + { + global $user, $langs; + + $langs->load('multicompany@multicompany'); + + $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.'entity'; + $res = $this->db->query($sql); + if ($res) $num = $this->db->fetch_array($res); + else dol_print_error($this->db); + + if (empty($num[0])) + { + $this->db->begin(); + + $now = dol_now(); + + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'entity ('; + $sql.= 'label'; + $sql.= ', description'; + $sql.= ', datec'; + $sql.= ', fk_user_creat'; + $sql.= ') VALUES ('; + $sql.= '\''.$langs->trans("MasterEntity").'\''; + $sql.= ', \''.$langs->trans("MasterEntityDesc").'\''; + $sql.= ', \''.$this->db->idate($now).'\''; + $sql.= ', '.$user->id; + $sql.= ')'; + + if ($this->db->query($sql)) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + return 0; + } + } +} diff --git a/htdocs/custom/multicompany/core/triggers/index.html b/htdocs/custom/multicompany/core/triggers/index.html new file mode 100755 index 00000000000..e69de29bb2d diff --git a/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php b/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php new file mode 100755 index 00000000000..a8b444a7417 --- /dev/null +++ b/htdocs/custom/multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php @@ -0,0 +1,86 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file /multicompany/core/triggers/interface_25_modMulticompany_MulticompanyWorkflow.class.php + * \ingroup multicompany + * \brief Trigger file for create multicompany data + */ + +require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; + +/** + * \class InterfaceMulticompanyWorkflow + * \brief Classe des fonctions triggers des actions personnalisees du module multicompany + */ + +class InterfaceMulticompanyWorkflow extends DolibarrTriggers +{ + public $family = 'multicompany'; + + public $description = "Triggers of this module allows to create multicompany data"; + + /** + * Version of the trigger + * + * @var string + */ + public $version = self::VERSION_DOLIBARR; + + /** + * + * @var string Image of the trigger + */ + public $picto = 'multicompany@multicompany'; + + /** + * Function called when a Dolibarrr business event is done. + * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/core/triggers (and declared) + * + * Following properties may be set before calling trigger. The may be completed by this trigger to be used for writing the event into database: + * $object->id (id of entity) + * $object->element (element type of object) + * + * @param string $action Event action code + * @param Object $object Object + * @param User $user Object user + * @param Translate $langs Object langs + * @param conf $conf Object conf + * @return int <0 if KO, 0 if no triggered ran, >0 if OK + */ + public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) + { + // Mettre ici le code a executer en reaction de l'action + // Les donnees de l'action sont stockees dans $object + + /*if ($action == 'COMPANY_CREATE') + { + $entity = GETPOST('new_entity', 'int', 2); // limit to POST + + if ($entity > 0) + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ". __FILE__ .". id=".$object->rowid); + + return $ret; + } + }*/ + + return 0; + } + +} diff --git a/htdocs/custom/multicompany/css/dropdown.inc.php b/htdocs/custom/multicompany/css/dropdown.inc.php new file mode 100755 index 00000000000..ef91f9078cb --- /dev/null +++ b/htdocs/custom/multicompany/css/dropdown.inc.php @@ -0,0 +1,199 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +if (! defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); +$colorbackhmenu1='60,70,100'; // topmenu +?> +/* '; if (empty($hidelabel)) { @@ -1264,7 +1268,7 @@ class Form } } else { // Immediate load of all database - $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple); + $out .= $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple, $excludeids); } return $out; @@ -1277,7 +1281,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 NOT IN (x)', 's.client IN (1,3)'). Do not use a filter coming from input of users. * @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 @@ -1288,9 +1292,10 @@ class Form * @param string $morecss Add more css styles to the SELECT component * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param bool $multiple add [] in the name of element and add 'multiple' attribut + * @param array $excludeids Exclude IDs from the select combo * @return string HTML string with */ - public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false) + public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false, $excludeids = array()) { // phpcs:enable global $conf, $user, $langs; @@ -1338,6 +1343,9 @@ class Form if (!empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) { $sql .= " AND s.status <> 0"; } + if (!empty($excludeids)) { + $sql .= " AND rowid NOT IN (".$this->db->sanitize(join(',', $excludeids)).")"; + } // Add criteria if ($filterkey && $filterkey != '') { $sql .= " AND ("; @@ -5472,15 +5480,16 @@ class Form * @param string $page Page * @param string $selected Id preselected * @param string $htmlname Name of HTML select - * @param string $filter optional filters criteras + * @param string $filter Optional filters criteras. Do not use a filter coming from input of users. * @param int $showempty Add an empty field * @param int $showtype Show third party type in combolist (customer, prospect or supplier) * @param int $forcecombo Force to use combo box * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param int $nooutput No print output. Return it only. + * @param array $excludeids Exclude IDs from the select combo * @return void|string */ - public function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0) + public function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0, $excludeids = array()) { // phpcs:enable global $langs; @@ -5490,7 +5499,7 @@ class Form $out .= '
'; $out .= ''; $out .= ''; - $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events); + $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, 0, 'minwidth100', '', '', 1, array(), false, $excludeids); $out .= ''; $out .= '
'; } else { diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index ba33386f360..57edbcebc1d 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -48,6 +48,7 @@ $filter = GETPOST('filter', 'alpha'); $outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0); $action = GETPOST('action', 'aZ09'); $id = GETPOST('id', 'int'); +$excludeids = GETPOST('excludeids', 'intcomma'); $showtype = GETPOST('showtype', 'int'); @@ -102,6 +103,11 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { if (!is_object($form)) { $form = new Form($db); } + + if (!empty($excludeids)) { + $filter .= 'rowid NOT IN ('.$db->sanitize($excludeids).')'; + } + $arrayresult = $form->select_thirdparty_list(0, $htmlname, $filter, 1, $showtype, 0, null, $searchkey, $outjson); $db->close(); diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index e7d40037155..d42ed635e82 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2399,7 +2399,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { 'name' => 'soc_origin', 'label' => $langs->trans('MergeOriginThirdparty'), 'type' => 'other', - 'value' => $form->select_company('', 'soc_origin', 's.rowid <> '.$object->id, 'SelectThirdParty', 0, 0, array(), 0, 'minwidth200') + 'value' => $form->select_company('', 'soc_origin', '', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth200', '', '', 1, null, false, array($object->id)) ) ); @@ -2773,7 +2773,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; print ''; $html_name = ($action == 'editparentcompany') ? 'parent_id' : 'none'; - $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->parent, $html_name, 's.rowid <> '.$object->id, 1); + $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->parent, $html_name, '', 1, 0, 0, null, 0, array($object->id)); print ''; } From 2d5fbfc105ce5d5962632d54c663fe3c40f89e18 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 22 Mar 2021 23:43:28 +0100 Subject: [PATCH 114/207] Fix php8 --- .../compta/paiement/class/paiement.class.php | 2 +- htdocs/fourn/class/paiementfourn.class.php | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 91759ad824f..9dcc57a47f2 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -1167,7 +1167,7 @@ class Paiement extends CommonObject $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $label = $langs->trans("ShowMyObject"); + $label = $langs->trans("Payment"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 41c780f70c8..b64cd32e4d6 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -529,9 +529,10 @@ class PaiementFourn extends Paiement * @param string $option Sur quoi pointe le lien * @param string $mode 'withlistofinvoices'=Include list of invoices into tooltip * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more CSS * @return string Chaine avec URL */ - public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0) + public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '') { global $langs; @@ -547,13 +548,26 @@ class PaiementFourn extends Paiement $text = $langs->trans($reg[1]); } - $label = ''.$langs->trans("Payment").'
'; + $label = img_picto('', $this->picto).' '.$langs->trans("Payment").'
'; $label .= ''.$langs->trans("Ref").': '.$text; if ($this->datepaye ? $this->datepaye : $this->date) { - $label .= '
'.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour'); + $label .= '
'.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour', 'tzuser'); } - $linkstart = ''; + $linkclose = ''; + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $label = $langs->trans("Payment"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } + + $linkstart = ''; $linkend = ''; $result .= $linkstart; From bc9b4fa637f6722c418ab3444c86d4e50ce95cce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 23 Mar 2021 00:35:30 +0100 Subject: [PATCH 115/207] Fix id --- htdocs/install/mysql/data/llx_accounting_account_dz.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/data/llx_accounting_account_dz.sql b/htdocs/install/mysql/data/llx_accounting_account_dz.sql index 0a80cf0f4b4..3895c1ff604 100644 --- a/htdocs/install/mysql/data/llx_accounting_account_dz.sql +++ b/htdocs/install/mysql/data/llx_accounting_account_dz.sql @@ -24,7 +24,7 @@ -- ID 15000 - 15811 -- ADD 1300000 to rowid # Do no remove this comment -- -INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (17000,'NSCF','CAPIT','1',0,'Comptes de capitaux','1'); +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (15000,'NSCF','CAPIT','1',0,'Comptes de capitaux','1'); INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (15001,'NSCF','CAPIT','10',17000,'Capital, réserves et assimilés','1'); INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (15002,'NSCF','CAPIT','101',15001,'Capital émis','1'); INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (15003,'NSCF','CAPIT','1011',15002,'Capital souscrit, non appelé','1'); From e3b019f92373bbc2c195a40e1a35f8eabcc62be2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 23 Mar 2021 01:32:17 +0100 Subject: [PATCH 116/207] Clean code --- htdocs/adherents/card.php | 36 +++++++++---------- htdocs/adherents/class/adherent.class.php | 2 +- htdocs/adherents/index.php | 2 +- htdocs/admin/eventorganization.php | 4 +-- htdocs/core/lib/functions.lib.php | 10 +++--- .../modules/modEventOrganization.class.php | 6 ++-- .../class/conferenceorbooth.class.php | 2 +- .../conferenceorbooth_list.php | 4 +-- htdocs/langs/en_US/eventorganization.lang | 4 +-- .../core/modules/modMyModule.class.php | 2 ++ htdocs/theme/eldy/badges.inc.php | 4 +-- htdocs/theme/eldy/btn.inc.php | 2 +- htdocs/theme/eldy/theme_vars.inc.php | 1 + htdocs/theme/md/badges.inc.php | 24 +++++++++++-- htdocs/theme/md/theme_vars.inc.php | 1 + 15 files changed, 65 insertions(+), 39 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 57e510719bb..b75bce38ca9 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1830,7 +1830,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Send if (empty($user->socid)) { if ($object->statut == 1) { - print ''; + print ''."\n"; } } @@ -1856,17 +1856,17 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Modify if ($user->rights->adherent->creer) { - print '"; + print ''."\n"; } else { - print '
'.$langs->trans("Modify").'
'; + print '
'.$langs->trans("Modify").'
'."\n"; } // Validate if ($object->statut == -1) { if ($user->rights->adherent->creer) { - print '\n"; + print ''."\n"; } else { - print '
'.$langs->trans("Validate").'
'; + print '
'.$langs->trans("Validate").'
'."\n"; } } @@ -1875,7 +1875,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($user->rights->adherent->creer) { print '\n"; } else { - print '
'.$langs->trans("Reenable")."
"; + print '
'.$langs->trans("Reenable").'
'."\n"; } } @@ -1884,7 +1884,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($user->rights->adherent->supprimer) { print '\n"; } else { - print '
'.$langs->trans("Resiliate")."
"; + print '
'.$langs->trans("Resiliate").'
'."\n"; } } @@ -1893,7 +1893,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($user->rights->adherent->supprimer) { print '\n"; } else { - print '
'.$langs->trans("Exclude")."
"; + print '
'.$langs->trans("Exclude").'
'."\n"; } } @@ -1901,12 +1901,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (!empty($conf->societe->enabled) && !$object->socid) { if ($user->rights->societe->creer) { if ($object->statut != -1) { - print ''; + print ''."\n";; } else { - print ''; + print ''."\n"; } } else { - print '
'.$langs->trans("CreateDolibarrThirdParty")."
"; + print '
'.$langs->trans("CreateDolibarrThirdParty").'
'."\n"; } } @@ -1914,12 +1914,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (!$user->socid && !$object->user_id) { if ($user->rights->user->user->creer) { if ($object->statut != -1) { - print ''; + print ''."\n"; } else { - print ''; + print ''."\n"; } } else { - print '
'.$langs->trans("CreateDolibarrLogin")."
"; + print '
'.$langs->trans("CreateDolibarrLogin").'
'."\n"; } } @@ -1928,18 +1928,18 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $isinspip = $mailmanspip->is_in_spip($object); if ($isinspip == 1) { - print '\n"; + print ''."\n"; } if ($isinspip == 0) { - print '\n"; + print ''."\n"; } } // Delete if ($user->rights->adherent->supprimer) { - print '\n"; + print ''."\n"; } else { - print '
'.$langs->trans("Delete")."
"; + print '
'.$langs->trans("Delete").'
'."\n"; } } } diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index bb56eaf4947..8803ce032fa 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2279,7 +2279,7 @@ class Adherent extends CommonObject $labelStatus = $langs->trans("MemberStatusResiliated"); $labelStatusShort = $langs->trans("MemberStatusResiliatedShort"); } elseif ($status == -2) { - $statusType = 'status8'; + $statusType = 'status10'; $labelStatus = $langs->trans("MemberStatusExcluded"); $labelStatusShort = $langs->trans("MemberStatusExcludedShort"); } diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 517649c4b61..803ef89bb22 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -233,7 +233,7 @@ if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->SetDataColor(array($badgeStatus1, $badgeStatus4, $badgeStatus8, $badgeStatus6, '-'.$badgeStatus0)); + $dolgraph->SetDataColor(array($badgeStatus1, $badgeStatus4, '-'.$badgeStatus8, $badgeStatus6, '-'.$badgeStatus0)); $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index 8625f182f47..23fc463f3b5 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -201,7 +201,7 @@ if ($action == 'edit') { print ''; print ''; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled']==1) { @@ -266,7 +266,7 @@ if ($action == 'edit') { } else { if (!empty($arrayofparameters)) { print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print ''; + print ''; foreach ($arrayofparameters as $constname => $val) { if ($val['enabled']==1) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ab9a476c923..948ddc09499 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3524,7 +3524,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'info', 'intervention', 'inventory', 'label', 'language', 'link', 'list', 'listlight', 'loan', 'lot', 'long-arrow-alt-right', 'margin', 'map-marker-alt', 'member', 'meeting', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', 'object_accounting', 'object_account', 'object_accountline', 'object_action', 'object_asset', 'object_barcode', 'object_bill', 'object_billr', 'object_billa', 'object_billd', 'object_bom', - 'object_category', 'object_conversation', 'object_bookmark', 'object_bug', 'object_clock', 'object_dolly', 'object_dollyrevert', + 'object_category', 'conferenceorbooth', 'object_conversation', 'object_bookmark', 'object_bug', 'object_clock', 'object_dolly', 'object_dollyrevert', 'object_folder', 'object_folder-open','object_generic', 'object_list-alt', 'object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser', 'object_cash-register', 'object_company', 'object_contact', 'object_contract', 'object_cron', 'object_donation', 'object_dynamicprice', @@ -3549,7 +3549,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'shapes', 'supplier_proposal', 'supplier_order', 'supplier_invoice', 'timespent', 'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda', 'user-cog', 'website', - 'eventorganization', 'object_eventorganization' + 'conferenceorbooth', 'eventorganization', 'object_eventorganization' ))) { $pictowithouttext = str_replace('object_', '', $pictowithouttext); @@ -3597,7 +3597,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'uparrow'=>'mail-forward', 'vcard'=>'address-card', 'jabber'=>'comment-o', 'website'=>'globe-americas', - 'eventorganization'=>'id-badge' + 'conferenceorbooth'=>'chalkboard-teacher', 'eventorganization'=>'project-diagram' ); if ($pictowithouttext == 'off') { $fakey = 'fa-square'; @@ -3630,7 +3630,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ if (in_array($pictowithouttext, array('dollyrevert', 'member', 'members', 'contract', 'group', 'resource', 'shipment'))) { $morecss = 'em092'; } - if (in_array($pictowithouttext, array('collab', 'holiday', 'project'))) { + if (in_array($pictowithouttext, array('conferenceorbooth', 'collab', 'eventorganization', 'holiday', 'project'))) { $morecss = 'em088'; } if (in_array($pictowithouttext, array('intervention', 'info', 'payment', 'loan', 'stock', 'technic'))) { @@ -3652,6 +3652,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'action'=>'infobox-action', 'account'=>'infobox-bank_account', 'accountline'=>'infobox-bank_account', 'accountancy'=>'infobox-bank_account', 'asset'=>'infobox-bank_account', 'bank_account'=>'bg-infobox-bank_account', 'bill'=>'infobox-commande', 'billa'=>'infobox-commande', 'billr'=>'infobox-commande', 'billd'=>'infobox-commande', + 'conferenceorbooth'=>'infobox-project', 'cash-register'=>'infobox-bank_account', 'contract'=>'infobox-contrat', 'check'=>'font-status4', 'collab'=>'infobox-action', 'conversation'=>'infobox-contrat', 'donation'=>'infobox-commande', 'dollyrevert'=>'flip', 'ecm'=>'infobox-action', 'hrm'=>'infobox-adherent', 'group'=>'infobox-adherent', 'intervention'=>'infobox-contrat', @@ -3661,6 +3662,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'user'=>'infobox-adherent', 'users'=>'infobox-adherent', 'error'=>'pictoerror', 'warning'=>'pictowarning', 'switch_on'=>'font-status4', 'holiday'=>'infobox-holiday', 'info'=>'opacityhigh', 'invoice'=>'infobox-commande', 'loan'=>'infobox-bank_account', + 'eventorganization'=>'infobox-project', 'payment'=>'infobox-bank_account', 'poll'=>'infobox-adherent', 'pos'=>'infobox-bank_account', 'project'=>'infobox-project', 'projecttask'=>'infobox-project', 'propal'=>'infobox-propal', 'recruitmentjobposition'=>'infobox-adherent', 'recruitmentcandidature'=>'infobox-adherent', 'resource'=>'infobox-action', diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 386da21d798..244b4f41cab 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -341,6 +341,7 @@ class modEventOrganization extends DolibarrModules 'fk_menu'=>'fk_mainmenu=project', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry 'titre'=>'EventOrganizationMenuLeft', + 'prefix' => img_picto('', 'eventorganization', 'class="paddingright pictofixedwidth"'), 'mainmenu'=>'project', 'leftmenu'=>'eventorganization', 'url'=>'', @@ -355,7 +356,7 @@ class modEventOrganization extends DolibarrModules 'fk_menu'=>'fk_mainmenu=project,fk_leftmenu=eventorganization', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry 'titre'=>'List', - 'url'=>'/projet/list.php?search_usage_event_organization=1&mainmenu=project', + 'url'=>'/projet/list.php?search_usage_event_organization=1&mainmenu=project&contextpage=organizedevents', 'langs'=>'eventorganization@eventorganization', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>1000+$r, 'enabled'=>'$conf->eventorganization->enabled', // Define condition to show or hide menu entry. Use '$conf->eventorganization->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. @@ -378,7 +379,8 @@ class modEventOrganization extends DolibarrModules $this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=project', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry - 'titre'=>'EventOrganizationMenuLeft', + 'titre'=>'ConferenceOrBooth', + 'prefix' => img_picto('', 'conferenceorbooth', 'class="paddingright pictofixedwidth"'), 'mainmenu'=>'project', 'leftmenu'=>'eventorganizationconforbooth', 'url'=>'', diff --git a/htdocs/eventorganization/class/conferenceorbooth.class.php b/htdocs/eventorganization/class/conferenceorbooth.class.php index 7f28d40dd29..d91181d0c51 100644 --- a/htdocs/eventorganization/class/conferenceorbooth.class.php +++ b/htdocs/eventorganization/class/conferenceorbooth.class.php @@ -61,7 +61,7 @@ class ConferenceOrBooth extends ActionComm /** * @var string String with name of icon for conferenceorbooth. Must be the part after the 'object_' into object_conferenceorbooth.png */ - public $picto = 'conferenceorbooth@eventorganization'; + public $picto = 'conferenceorbooth'; const STATUS_DRAFT = 0; diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index ea189d4be9b..89e614cc3ba 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -554,9 +554,9 @@ print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/eventorganization/conferenceorbooth_card.php', 1).'?action=create'.(!empty($project->id)?'&fk_project='.$project->id:'').(!empty($project->socid)?'&fk_soc='.$project->socid:'').'&backtopage='.urlencode($_SERVER['PHP_SELF']).(!empty($project->id)?'?projectid='.$project->id:''), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/eventorganization/conferenceorbooth_card.php?action=create'.(!empty($project->id)?'&fk_project='.$project->id:'').(!empty($project->socid)?'&fk_soc='.$project->socid:'').'&backtopage='.urlencode($_SERVER['PHP_SELF']).(!empty($project->id)?'?projectid='.$project->id:''), '', $permissiontoadd); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) $topicmail = "SendConferenceOrBoothRef"; diff --git a/htdocs/langs/en_US/eventorganization.lang b/htdocs/langs/en_US/eventorganization.lang index 5444ed59e3d..82f18107a5c 100644 --- a/htdocs/langs/en_US/eventorganization.lang +++ b/htdocs/langs/en_US/eventorganization.lang @@ -32,8 +32,8 @@ EventOrganizationConferenceOrBoothMenuLeft = Conference Or Booth EventOrganizationSetup = Event Organization setup Settings = Settings EventOrganizationSetupPage = Event Organization setup page -EVENTORGANIZATION_TASK_LABEL = Task label created when validate -EVENTORGANIZATION_TASK_LABELTooltip = When validate a Conference or a booth, some tasks will be created in the project

for example:
Send Call for Conference
Send Call for Booth
Receive call for conferences
Receive call for Booth
Open subscriptions to events for attendees
Send remind of event to speakers
Send remind of event to Booth hoster
Send remind of event to attendees +EVENTORGANIZATION_TASK_LABEL = Label of tasks to create automatically when project is validated +EVENTORGANIZATION_TASK_LABELTooltip = When you validate an organized event, some tasks can be automatically created in the project

For example:
Send Call for Conference
Send Call for Booth
Receive call for conferences
Receive call for Booth
Open subscriptions to events for attendees
Send remind of event to speakers
Send remind of event to Booth hoster
Send remind of event to attendees EVENTORGANIZATION_CATEG_THIRDPARTY_CONF = Category to add to third-parties automatically created when someone suggests a conference EVENTORGANIZATION_CATEG_THIRDPARTY_BOOTH = Category to add to third-parties automatically created when they suggests a booth EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF = Template of email to send after receiving a suggestion of a conference. diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index e4f662c9e99..322c043a26c 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -290,6 +290,7 @@ class modMyModule extends DolibarrModules 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'top', // This is a Top menu entry 'titre'=>'ModuleMyModuleName', + 'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth"'), 'mainmenu'=>'mymodule', 'leftmenu'=>'', 'url'=>'/mymodule/mymoduleindex.php', @@ -306,6 +307,7 @@ class modMyModule extends DolibarrModules 'fk_menu'=>'fk_mainmenu=mymodule', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Top menu entry 'titre'=>'MyObject', + 'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth"'), 'mainmenu'=>'mymodule', 'leftmenu'=>'myobject', 'url'=>'/mymodule/mymoduleindex.php', diff --git a/htdocs/theme/eldy/badges.inc.php b/htdocs/theme/eldy/badges.inc.php index f3f311eccca..dcb61499b63 100644 --- a/htdocs/theme/eldy/badges.inc.php +++ b/htdocs/theme/eldy/badges.inc.php @@ -205,7 +205,7 @@ a.badge-dark:focus, a.badge-dark:hover { /* STATUS BADGES */ em; + margin: 0em em; padding: 0.6em em; display: inline-block; text-align: center; diff --git a/htdocs/theme/eldy/theme_vars.inc.php b/htdocs/theme/eldy/theme_vars.inc.php index 8bb2fd3bbca..82cbf9cf2a9 100644 --- a/htdocs/theme/eldy/theme_vars.inc.php +++ b/htdocs/theme/eldy/theme_vars.inc.php @@ -114,6 +114,7 @@ $badgeStatus6 = '#cad2d2'; $badgeStatus7 = '#25a580'; $badgeStatus8 = '#993013'; $badgeStatus9 = '#e7f0f0'; +$badgeStatus10 = '#993013'; // status color ajustement for color blind $colorblind_deuteranopes_badgeStatus4 = $colorblind_deuteranopes_badgeStatus7 = $colorblind_deuteranopes_badgeSuccess; //! text color black diff --git a/htdocs/theme/md/badges.inc.php b/htdocs/theme/md/badges.inc.php index 7dd0229ae46..fd1b1122a17 100644 --- a/htdocs/theme/md/badges.inc.php +++ b/htdocs/theme/md/badges.inc.php @@ -1,7 +1,8 @@ +} +?> /* + + + '> + + + + + From 7c2e3c49309c875aab7890ebf075975d5c0a78e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Mar 2021 14:47:10 +0100 Subject: [PATCH 193/207] Removed old deprecated API browser --- htdocs/api/admin/explorer.php | 216 ---------------------------------- 1 file changed, 216 deletions(-) delete mode 100644 htdocs/api/admin/explorer.php diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php deleted file mode 100644 index 53b9233c130..00000000000 --- a/htdocs/api/admin/explorer.php +++ /dev/null @@ -1,216 +0,0 @@ - - * Copyright (C) 2016 Laurent Destailleur - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * @deprecated Old explorer. Not using Swagger. See instead explorer in htdocs/api/index.php. - */ - -/** - * \defgroup api Module DolibarrApi - * \brief API loader - * Search files htdocs//class/api_.class.php - * \file htdocs/api/admin/explorer.php - */ - -use Luracast\Restler\Routes; - -require_once '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; -require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; - -// Load translation files required by the page -$langs->load("admin"); - - -/* - * View - */ - -// Enable and test if module Api is enabled -if (empty($conf->global->MAIN_MODULE_API)) { - dol_syslog("Call Dolibarr API interfaces with module REST disabled"); - print $langs->trans("WarningModuleNotActive", 'Api').'.

'; - print $langs->trans("ToActivateModule"); - exit; -} - - -$api = new DolibarrApi($db); - -$api->r->addAPIClass('Luracast\\Restler\\Resources'); //this creates resources.json at API Root -$api->r->setSupportedFormats('JsonFormat', 'XmlFormat'); -$api->r->addAuthenticationClass('DolibarrApiAccess', ''); - -$listofapis = array(); - -$modulesdir = dolGetModulesDirs(); -foreach ($modulesdir as $dir) { - /* - * Search available module - */ - //dol_syslog("Scan directory ".$dir." for API modules"); - - $handle = @opendir(dol_osencode($dir)); - if (is_resource($handle)) { - while (($file = readdir($handle)) !== false) { - if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i", $file, $reg)) { - $modulename = $reg[1]; - - // Defined if module is enabled - $enabled = true; - $module = $part = $obj = strtolower(preg_replace('/^mod/i', '', $modulename)); - //if ($part == 'propale') $part='propal'; - if ($module == 'societe') { - $obj = 'thirdparty'; - } - if ($module == 'categorie') { - $part = 'categories'; - $obj = 'category'; - } - if ($module == 'facture') { - $part = 'compta/facture'; - $obj = 'facture'; - } - if ($module == 'ficheinter') { - $obj = 'fichinter'; - $part = 'fichinter'; - $module = 'fichinter'; - } - - if (empty($conf->$module->enabled)) { - $enabled = false; - } - - if ($enabled) { - /* - * If exists, load the API class for enable module - * - * Search files named api_.class.php into /htdocs//class directory - * - * @todo : take care of externals module! - * @todo : use getElementProperties() function ? - */ - $dir_part = DOL_DOCUMENT_ROOT.'/'.$part.'/class/'; - - $handle_part = @opendir(dol_osencode($dir_part)); - if (is_resource($handle_part)) { - while (($file_searched = readdir($handle_part)) !== false) { - if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i", $file_searched, $reg)) { - $classname = ucwords($reg[1]); - require_once $dir_part.$file_searched; - if (class_exists($classname)) { - dol_syslog("Found API classname=".$classname." into ".$dir); - $listofapis[] = $classname; - } - } - - /* - if (is_readable($dir_part.$file_searched) && preg_match("/^(api_.*)\.class\.php$/i",$file_searched,$reg)) - { - $classname=$reg[1]; - $classname = str_replace('Api_','',ucwords($reg[1])).'Api'; - //$classname = str_replace('Api_','',ucwords($reg[1])); - $classname = ucfirst($classname); - require_once $dir_part.$file_searched; - - // if (class_exists($classname)) - // { - // dol_syslog("Found API classname=".$classname); - // $api->r->addAPIClass($classname,''); - - // require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/Routes.php'; - // $tmpclass = new ReflectionClass($classname); - // try { - // $classMetadata = CommentParser::parse($tmpclass->getDocComment()); - // } catch (Exception $e) { - // throw new RestException(500, "Error while parsing comments of `$classname` class. " . $e->getMessage()); - // } - - // //$listofapis[]=array('classname'=>$classname, 'fullpath'=>$file_searched); - // } - }*/ - } - } - } - } - } - } -} - -//var_dump($listofapis); -$listofapis = Routes::toArray(); // @todo api for "status" is lost here -//var_dump($listofapis); - - -llxHeader(); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ApiSetup"), $linkback, 'title_setup'); - -// Define $urlwithroot -$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); -$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file -//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - -// Show message -print '
'; -$message = ''; -$url = ''.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword[&reset=1]'; -$message .= $langs->trans("UrlToGetKeyToUseAPIs").':
'; -$message .= img_picto('', 'globe').' '.$url; -print $message; -print '
'; -print '
'; - -$oldclass = ''; - -print $langs->trans("ListOfAvailableAPIs").':
'; -foreach ($listofapis['v1'] as $key => $val) { - if ($key == 'login') { - continue; - } - if ($key == 'index') { - continue; - } - - if ($key) { - foreach ($val as $method => $val2) { - $newclass = $val2['className']; - - if (preg_match('/restler/i', $newclass)) { - continue; - } - - if ($oldclass != $newclass) { - print "\n
\n".$langs->trans("Class").': '.$newclass.'
'."\n"; - $oldclass = $newclass; - } - //print $key.' - '.$val['classname'].' - '.$val['fullpath']." - ".DOL_MAIN_URL_ROOT.'/api/index.php/'.strtolower(preg_replace('/Api$/','',$val['classname']))."/xxx
\n"; - $url = $urlwithroot.'/api/index.php/'.$key; - $url .= '?api_key=token'; - print img_picto('', 'globe').' '.$method.' '.$url."
\n"; - } - } -} - -print '
'; -print '
'; -print $langs->trans("OnlyActiveElementsAreExposed", DOL_URL_ROOT.'/admin/modules.php'); - - -llxFooter(); -$db->close(); From a4ca16db32afccd28176194f982b779dfa0fbf6c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Mar 2021 14:48:14 +0100 Subject: [PATCH 194/207] Doc --- htdocs/api/admin/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 45fa87a2e77..3299435a10d 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -152,7 +152,7 @@ if (dol_is_dir(DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/e $url = DOL_MAIN_URL_ROOT.'/api/index.php/explorer'; print img_picto('', 'globe').' '.$url."
\n"; print '

'.$langs->trans("SwaggerDescriptionFile").':
'; - $urlswagger = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY=useauserapikey'; + $urlswagger = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY=youruserapikey'; print img_picto('', 'globe').' '.$urlswagger."
\n"; print '
'; } else { From 3a5f130ed578b9f080e4afb747bae7f4956ac76c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Mar 2021 14:54:12 +0100 Subject: [PATCH 195/207] Add protections --- htdocs/api/admin/explorer_withredoc.php | 32 +++++++++++++++++++++++++ htdocs/api/index.php | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/htdocs/api/admin/explorer_withredoc.php b/htdocs/api/admin/explorer_withredoc.php index 08711abede2..45dd31d57c9 100644 --- a/htdocs/api/admin/explorer_withredoc.php +++ b/htdocs/api/admin/explorer_withredoc.php @@ -26,6 +26,38 @@ require_once '../../main.inc.php'; +// Enable and test if module Api is enabled +if (empty($conf->global->MAIN_MODULE_API)) { + $langs->load("admin"); + dol_syslog("Call of Dolibarr API interfaces with module API REST are disabled"); + print $langs->trans("WarningModuleNotActive", 'Api').'.

'; + print $langs->trans("ToActivateModule"); + //session_destroy(); + exit(0); +} + +// Test if explorer is not disabled +if (!empty($conf->global->API_EXPLORER_DISABLED)) { + $langs->load("admin"); + dol_syslog("Call Dolibarr API interfaces with module REST disabled"); + print $langs->trans("WarningAPIExplorerDisabled").'.

'; + //session_destroy(); + exit(0); +} + +// Restrict API to some IPs +if (!empty($conf->global->API_RESTRICT_ON_IP)) { + $allowedip = explode(' ', $conf->global->API_RESTRICT_ON_IP); + $ipremote = getUserRemoteIP(); + if (!in_array($ipremote, $allowedip)) { + dol_syslog('Remote ip is '.$ipremote.', not into list '.$conf->global->API_RESTRICT_ON_IP); + print 'APIs are not allowed from the IP '.$ipremote; + header('HTTP/1.1 503 API not allowed from your IP '.$ipremote); + //session_destroy(); + exit(0); + } +} + ?> diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 880d3263aaa..89b5a696462 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -95,7 +95,7 @@ if (!empty($conf->global->MAIN_NGINX_FIX)) { // Enable and test if module Api is enabled if (empty($conf->global->MAIN_MODULE_API)) { $langs->load("admin"); - dol_syslog("Call Dolibarr API interfaces with module REST disabled"); + dol_syslog("Call of Dolibarr API interfaces with module API REST are disabled"); print $langs->trans("WarningModuleNotActive", 'Api').'.

'; print $langs->trans("ToActivateModule"); //session_destroy(); From 4a22c8e87e4aea7973711056e779abfa674fa2bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Mar 2021 15:12:39 +0100 Subject: [PATCH 196/207] CSS --- htdocs/api/admin/index.php | 6 +++--- htdocs/theme/eldy/global.inc.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 3299435a10d..05f372a3486 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -141,7 +141,7 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai $message = ''; $url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; $message .= ''.$langs->trans("UrlToGetKeyToUseAPIs").':
'; -$message .= img_picto('', 'globe').' '.$url; +$message .= ''; print $message; print '
'; print '
'; @@ -150,10 +150,10 @@ print '
'; print ''.$langs->trans("ApiExporerIs").':
'; if (dol_is_dir(DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/explorer')) { $url = DOL_MAIN_URL_ROOT.'/api/index.php/explorer'; - print img_picto('', 'globe').' '.$url."
\n"; + print '
\n"; print '

'.$langs->trans("SwaggerDescriptionFile").':
'; $urlswagger = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY=youruserapikey'; - print img_picto('', 'globe').' '.$urlswagger."
\n"; + print '
\n"; print '
'; } else { $langs->load("errors"); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index f14c7bba87f..62d040f2aff 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -767,6 +767,19 @@ textarea.centpercent { max-width: 100%; overflow-y: auto; } +div.urllink { + padding: 10px; + margin-top: 5px; + margin-bottom: 5px; + //border: 1px solid #ccc; + border-radius: 5px; + width: fit-content; + background-color: #eee; + opacity: 0.8; +} +div.urllink, div.urllink a { + color: #339 !important; +} i.fa-mars::before, i.fa-venus::before, i.fa-genderless::before { color: #888 !important; From 84ec032cc0215e89b745d74adcb3b0d9db6acab1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 26 Mar 2021 17:58:00 +0100 Subject: [PATCH 197/207] Look and feel v14 --- htdocs/api/admin/index.php | 15 ++++++----- htdocs/core/ajax/selectsearchbox.php | 2 +- htdocs/core/class/html.form.class.php | 9 ++++--- htdocs/core/lib/functions.lib.php | 4 +-- htdocs/core/lib/payments.lib.php | 4 +-- htdocs/core/lib/signature.lib.php | 10 ++++++-- htdocs/theme/eldy/global.inc.php | 10 ++++---- htdocs/theme/eldy/main_menu_fa_icons.inc.php | 2 +- htdocs/theme/md/main_menu_fa_icons.inc.php | 2 +- htdocs/theme/md/style.css.php | 27 ++++++++++++++++---- 10 files changed, 56 insertions(+), 29 deletions(-) diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 05f372a3486..1697318c5e8 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -139,21 +139,24 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai // Show message $message = ''; -$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; +//$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; +$url = $urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; $message .= ''.$langs->trans("UrlToGetKeyToUseAPIs").':
'; -$message .= ''; +$message .= ''; print $message; +print ajax_autoselect("urltogettoken"); print '
'; print '
'; // Explorer -print ''.$langs->trans("ApiExporerIs").':
'; +print ''.$langs->trans("ApiExporerIs").':
'; if (dol_is_dir(DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/explorer')) { $url = DOL_MAIN_URL_ROOT.'/api/index.php/explorer'; - print '
\n"; - print '

'.$langs->trans("SwaggerDescriptionFile").':
'; + print '
\n"; + print '

'.$langs->trans("SwaggerDescriptionFile").':
'; $urlswagger = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY=youruserapikey'; - print '
\n"; + //$urlswaggerreal = DOL_MAIN_URL_ROOT.'/api/index.php/explorer/swagger.json?DOLAPIKEY='.$user->api_key; + print '
\n"; print '
'; } else { $langs->load("errors"); diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index 2794243b7f3..d10324ef620 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -81,7 +81,7 @@ if (((!empty($conf->product->enabled) && $user->rights->produit->lire) || (!empt $arrayresult['searchintoproduct'] = array('position'=>30, 'shortcut'=>'P', 'img'=>'object_product', 'label'=>$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'text'=>img_picto('', 'object_product').' '.$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); // search on lot/serial numbers if ( ! empty($conf->productbatch->enabled) ) { - $arrayresult['searchintobatch'] = array('position'=>32, 'shortcut'=>'B', 'img'=>'object_plot', 'label'=>$langs->trans("SearchIntoBatch", $search_boxvalue), 'text'=>img_picto('', 'object_lot').' '.$langs->trans("SearchIntoBatch", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/stock/productlot_list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); + $arrayresult['searchintobatch'] = array('position'=>32, 'shortcut'=>'B', 'img'=>'object_lot', 'label'=>$langs->trans("SearchIntoBatch", $search_boxvalue), 'text'=>img_picto('', 'object_lot').' '.$langs->trans("SearchIntoBatch", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/stock/productlot_list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 36e7eca84b6..21c886cb2fa 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7721,16 +7721,17 @@ class Form print '
'; print ''; - print ''; + print ''; print ''; print ''; + print ''.price($objp->total_ht).''; + print ''; print ''; print ''; $i++; @@ -7760,7 +7761,7 @@ class Form '; // Ref diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index b4c63365bf8..453abff36b2 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -1532,7 +1532,7 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['p.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1543,7 +1543,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['p.total_tva']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1554,7 +1554,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['p.total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1563,9 +1563,9 @@ if ($resql) { } $totalarray['val']['p.total_ttc'] += $obj->total_ttc; } - // Amount invoiced + // Amount invoiced HT if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1574,9 +1574,9 @@ if ($resql) { } $totalarray['val']['p.total_ht_invoiced'] += $totalInvoicedHT; } - // Amount invoiced + // Amount invoiced TTC if (!empty($arrayfields['p.total_invoiced']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1604,35 +1604,35 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['p.multicurrency_total_tva']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount invoiced if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount invoiced if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 117f7557db3..0b850e6b0e8 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1437,7 +1437,7 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['c.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1448,7 +1448,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['c.total_vat']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1459,7 +1459,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['c.total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1488,21 +1488,21 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['c.multicurrency_total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['c.multicurrency_total_vat']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['c.multicurrency_total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/core/boxes/box_members_last_subscriptions.php b/htdocs/core/boxes/box_members_last_subscriptions.php index 6da20bf28d0..e08bc1073b6 100644 --- a/htdocs/core/boxes/box_members_last_subscriptions.php +++ b/htdocs/core/boxes/box_members_last_subscriptions.php @@ -153,7 +153,7 @@ class box_members_last_subscriptions extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => 'class="right" width="18"', - 'text' => price($obj->subscription), + 'text' => ''.price($obj->subscription).'', ); $this->info_box_contents[$line][] = array( diff --git a/htdocs/core/boxes/box_members_subscriptions_by_year.php b/htdocs/core/boxes/box_members_subscriptions_by_year.php index ef796b75044..b6c146312bc 100644 --- a/htdocs/core/boxes/box_members_subscriptions_by_year.php +++ b/htdocs/core/boxes/box_members_subscriptions_by_year.php @@ -180,11 +180,11 @@ class box_members_subscriptions_by_year extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => price($value), + 'text' => ''.price($value).'', ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => price(price2num($value / $Number[$key], 'MT')), + 'text' => ''.price(price2num($value / $Number[$key], 'MT')).'', ); $line++; } @@ -205,11 +205,11 @@ class box_members_subscriptions_by_year extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="liste_total right"', - 'text' => price($tot), + 'text' => ''.price($tot).'', ); $this->info_box_contents[$line][] = array( 'td' => 'class="liste_total right"', - 'text' => price(price2num($numb > 0 ? ($tot / $numb) : 0, 'MT')), + 'text' => ''.price(price2num($numb > 0 ? ($tot / $numb) : 0, 'MT')).'', ); } } else { diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index e35d9d84824..09834f5c2af 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -1439,7 +1439,7 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['cf.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1450,7 +1450,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['cf.total_tva']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1461,7 +1461,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['cf.total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1490,21 +1490,21 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['cf.multicurrency_total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['cf.multicurrency_total_tva']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index e907ab3b06e..976e29b55bf 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -1107,7 +1107,7 @@ while ($i < min($num, $limit)) { print ''; @@ -1136,7 +1136,7 @@ while ($i < min($num, $limit)) { } print ''; @@ -1151,7 +1151,7 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['p.budget_amount']['checked'])) { print ''; @@ -1232,7 +1232,7 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['p.price_registration']['checked'])) { print ''; @@ -1247,7 +1247,7 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['p.price_booth']['checked'])) { print ''; diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 6851bbb4021..f60f20f7f7a 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -954,7 +954,7 @@ if ($resql) { // Amount HT if (!empty($arrayfields['sp.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -965,7 +965,7 @@ if ($resql) { } // Amount VAT if (!empty($arrayfields['sp.total_tva']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -976,7 +976,7 @@ if ($resql) { } // Amount TTC if (!empty($arrayfields['sp.total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } @@ -1005,21 +1005,21 @@ if ($resql) { } // Amount HT if (!empty($arrayfields['sp.multicurrency_total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount VAT if (!empty($arrayfields['sp.multicurrency_total_vat']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount TTC if (!empty($arrayfields['sp.multicurrency_total_ttc']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } From 50de0777e4513a0c3f82bbd95dffd6ae29f93658 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 12:45:57 +0100 Subject: [PATCH 199/207] Look and feel v14 --- htdocs/contact/list.php | 32 ++++++++++++++++++-------------- htdocs/societe/list.php | 9 ++++++--- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 3890155f116..4535c0514e9 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -704,25 +704,29 @@ $moreforfilter = ''; if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('Categories').': '; - $moreforfilter .= $formother->select_categories(Categorie::TYPE_CONTACT, $search_categ, 'search_categ', 1); + $tmptitle = $langs->trans('ContactCategoriesShort'); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $formother->select_categories(Categorie::TYPE_CONTACT, $search_categ, 'search_categ', 1, $tmptitle); $moreforfilter .= '
'; if (empty($type) || $type == 'c' || $type == 'p') { $moreforfilter .= '
'; + $tmptitle = ''; if ($type == 'c') { - $moreforfilter .= $langs->trans('CustomersCategoriesShort').': '; + $tmptitle .= $langs->trans('CustomersCategoriesShort'); } elseif ($type == 'p') { - $moreforfilter .= $langs->trans('ProspectsCategoriesShort').': '; + $tmptitle .= $langs->trans('ProspectsCategoriesShort'); } else { - $moreforfilter .= $langs->trans('CustomersProspectsCategoriesShort').': '; + $tmptitle .= $langs->trans('CustomersProspectsCategoriesShort'); } - $moreforfilter .= $formother->select_categories(Categorie::TYPE_CUSTOMER, $search_categ_thirdparty, 'search_categ_thirdparty', 1); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $formother->select_categories(Categorie::TYPE_CUSTOMER, $search_categ_thirdparty, 'search_categ_thirdparty', 1, $tmptitle); $moreforfilter .= '
'; } if (empty($type) || $type == 'f') { $moreforfilter .= '
'; - $moreforfilter .= $langs->trans('SuppliersCategoriesShort').': '; - $moreforfilter .= $formother->select_categories(Categorie::TYPE_SUPPLIER, $search_categ_supplier, 'search_categ_supplier', 1); + $tmptitle = $langs->trans('SuppliersCategoriesShort'); + $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $formother->select_categories(Categorie::TYPE_SUPPLIER, $search_categ_supplier, 'search_categ_supplier', 1, $tmptitle); $moreforfilter .= '
'; } } @@ -1092,35 +1096,35 @@ while ($i < min($num, $limit)) { } // Phone if (!empty($arrayfields['p.phone']['checked'])) { - print '
'; + print ''; if (!$i) { $totalarray['nbfield']++; } } // Phone perso if (!empty($arrayfields['p.phone_perso']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } // Phone mobile if (!empty($arrayfields['p.phone_mobile']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } // Fax if (!empty($arrayfields['p.fax']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } // EMail if (!empty($arrayfields['p.email']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } @@ -1144,7 +1148,7 @@ while ($i < min($num, $limit)) { } // Company if (!empty($arrayfields['p.fk_soc']['checked']) || !empty($arrayfields['s.nom']['checked'])) { - print ''; @@ -1546,9 +1546,9 @@ if ($resql) { print ''; @@ -1568,9 +1568,9 @@ if ($resql) { if ($product_fourn->product_fourn_price_id > 0) { if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire) { $htmltext = $product_fourn->display_price_product_fournisseur(1, 1, 0, 1); - print $form->textwithpicto(price($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent / 100) - $product_fourn->fourn_remise).' '.$langs->trans("HT"), $htmltext); + print ''.$form->textwithpicto(price($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent / 100) - $product_fourn->fourn_remise).' '.$langs->trans("HT"), $htmltext).''; } else { - print price($product_fourn->fourn_unitprice).' '.$langs->trans("HT"); + print ''.price($product_fourn->fourn_unitprice).' '.$langs->trans("HT").''; } } } @@ -1606,14 +1606,14 @@ if ($resql) { // WAP if (!empty($arrayfields['p.pmp']['checked'])) { print ''; } // Cost price if (!empty($arrayfields['p.cost_price']['checked'])) { print ''; } diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 1aafe3c6ae2..c8054683e52 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -280,14 +280,14 @@ if ($result) { $line = $total = $totalsell = $totalStock = 0; while ($line < $totalnboflines) { $objp = $db->fetch_object($result); - $total += price2num($objp->estimatedvalue, 'MU'); - $totalsell += price2num($objp->sellvalue, 'MU'); + $total += $objp->estimatedvalue; + $totalsell += $objp->sellvalue; $totalStock += $objp->stockqty; $line++; } - $totalarray['val']['stockqty'] = $totalStock; - $totalarray['val']['estimatedvalue'] = $total; - $totalarray['val']['estimatedstockvaluesell'] = $totalsell; + $totalarray['val']['stockqty'] = price2num($totalStock, 'MS'); + $totalarray['val']['estimatedvalue'] = price2num($total, 'MT'); + $totalarray['val']['estimatedstockvaluesell'] = price2num($totalsell, 'MT'); } $sql .= $db->order($sortfield, $sortorder); @@ -633,7 +633,7 @@ if ($num) { if (!empty($arrayfields["estimatedvalue"]['checked'])) { print ''; } diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 801c792cf7d..cb89a210e1e 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -128,26 +128,26 @@ if (empty($user->socid)) { } $arrayfields = array( - 't.fk_task_parent'=>array('label'=>$langs->trans("RefTaskParent"), 'checked'=>0, 'position'=>70), - 't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>80), - 't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>80), - 't.description'=>array('label'=>$langs->trans("Description"), 'checked'=>0, 'position'=>80), - 't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100), - 't.datee'=>array('label'=>$langs->trans("Deadline"), 'checked'=>1, 'position'=>101), - 'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>1), - 'p.title'=>array('label'=>$langs->trans("ProjectLabel"), 'checked'=>0), - 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>0), - 'p.fk_statut'=>array('label'=>$langs->trans("ProjectStatus"), 'checked'=>1), - 't.planned_workload'=>array('label'=>$langs->trans("PlannedWorkload"), 'checked'=>1, 'position'=>102), - 't.duration_effective'=>array('label'=>$langs->trans("TimeSpent"), 'checked'=>1, 'position'=>103), - 't.progress_calculated'=>array('label'=>$langs->trans("ProgressCalculated"), 'checked'=>1, 'position'=>104), - 't.progress'=>array('label'=>$langs->trans("ProgressDeclared"), 'checked'=>1, 'position'=>105), - 't.progress_summary'=>array('label'=>$langs->trans("TaskProgressSummary"), 'checked'=>1, 'position'=>106), - 't.tobill'=>array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>110), - 't.billed'=>array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>111), - 't.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), - 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - //'t.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 't.fk_task_parent'=>array('label'=>"RefTaskParent", 'checked'=>0, 'position'=>70), + 't.ref'=>array('label'=>"RefTask", 'checked'=>1, 'position'=>80), + 't.label'=>array('label'=>"LabelTask", 'checked'=>1, 'position'=>80), + 't.description'=>array('label'=>"Description", 'checked'=>0, 'position'=>80), + 't.dateo'=>array('label'=>"DateStart", 'checked'=>1, 'position'=>100), + 't.datee'=>array('label'=>"Deadline", 'checked'=>1, 'position'=>101), + 'p.ref'=>array('label'=>"ProjectRef", 'checked'=>1), + 'p.title'=>array('label'=>"ProjectLabel", 'checked'=>0), + 's.nom'=>array('label'=>"ThirdParty", 'checked'=>0), + 'p.fk_statut'=>array('label'=>"ProjectStatus", 'checked'=>1), + 't.planned_workload'=>array('label'=>"PlannedWorkload", 'checked'=>1, 'position'=>102), + 't.duration_effective'=>array('label'=>"TimeSpent", 'checked'=>1, 'position'=>103), + 't.progress_calculated'=>array('label'=>"ProgressCalculated", 'checked'=>1, 'position'=>104), + 't.progress'=>array('label'=>"ProgressDeclared", 'checked'=>1, 'position'=>105), + 't.progress_summary'=>array('label'=>"TaskProgressSummary", 'checked'=>1, 'position'=>106), + 't.tobill'=>array('label'=>"TimeToBill", 'checked'=>0, 'position'=>110), + 't.billed'=>array('label'=>"TimeBilled", 'checked'=>0, 'position'=>111), + 't.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), + //'t.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; From 95a7e13e3a9a3e5c21ae9dcfb3af13557e5e5828 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 14:54:09 +0100 Subject: [PATCH 204/207] Debug establishment --- htdocs/core/lib/functions.lib.php | 10 +-- htdocs/hrm/admin/admin_establishment.php | 13 ++- htdocs/hrm/admin/admin_hrm.php | 10 ++- htdocs/hrm/class/establishment.class.php | 90 +++++++++++++++---- htdocs/hrm/establishment/card.php | 28 ++++-- htdocs/hrm/establishment/info.php | 10 ++- .../modulebuilder/template/myobject_card.php | 2 +- 7 files changed, 120 insertions(+), 43 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 082faa99865..812c14792cf 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3528,17 +3528,17 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'accountancy', 'account', 'accountline', 'action', 'add', 'address', 'angle-double-down', 'angle-double-up', 'asset', 'bank_account', 'barcode', 'bank', 'bill', 'billa', 'billr', 'billd', 'bookmark', 'bom', 'building', 'cash-register', 'category', 'chart', 'check', 'clock', 'close_title', 'cog', 'collab', 'company', 'contact', 'country', 'contract', 'cron', 'cubes', - 'delete', 'dolly', 'dollyrevert', 'donation', 'download', 'edit', 'ellipsis-h', 'email', 'eraser', 'external-link-alt', 'external-link-square-alt', + 'delete', 'dolly', 'dollyrevert', 'donation', 'download', 'edit', 'ellipsis-h', 'email', 'eraser', 'establishment', 'external-link-alt', 'external-link-square-alt', 'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'group', 'help', 'holiday', 'info', 'intervention', 'inventory', 'intracommreport', 'label', 'language', 'link', 'list', 'listlight', 'loan', 'lot', 'long-arrow-alt-right', 'margin', 'map-marker-alt', 'member', 'meeting', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', 'object_accounting', 'object_account', 'object_accountline', 'object_action', 'object_asset', 'object_barcode', 'object_bill', 'object_billr', 'object_billa', 'object_billd', 'object_bom', - 'object_category', 'conferenceorbooth', 'object_conversation', 'object_bookmark', 'object_bug', 'object_clock', 'object_collab', 'object_dolly', 'object_dollyrevert', + 'object_category', 'conferenceorbooth', 'object_conversation', 'object_bookmark', 'object_bug', 'object_building', 'object_clock', 'object_collab', 'object_dolly', 'object_dollyrevert', 'object_folder', 'object_folder-open','object_generic', 'object_list-alt', 'object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser', - 'object_cash-register', 'object_company', 'object_contact', 'object_contract', 'object_cron', 'object_donation', 'object_dynamicprice', + 'object_cash-register', 'object_company', 'object_contact', 'object_contract', 'object_cron', 'object_donation', 'object_dynamicprice', 'object_establishment', 'object_globe', 'object_holiday', 'object_hrm', 'object_invoice', 'object_intervention', 'object_inventory', 'object_intracommreport', 'object_label', 'object_margin', 'object_members', 'object_money-bill-alt', 'object_multicurrency', 'object_order', 'object_payment', 'object_lot', 'object_mrp', 'object_other', @@ -3568,7 +3568,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ $facolor = ''; $fasize = ''; $fa = 'fas'; - if (in_array($pictowithouttext, array('clock', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) { + if (in_array($pictowithouttext, array('clock', 'establishment', 'generic', 'minus-square', 'object_generic', 'pdf', 'plus-square', 'timespent', 'note', 'off', 'on', 'object_bookmark', 'bookmark', 'vcard'))) { $fa = 'far'; } if (in_array($pictowithouttext, array('black-tie', 'github', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'stripe', 'stripe-s', 'youtube', 'google-plus-g', 'whatsapp'))) { @@ -3584,7 +3584,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'setup'=>'cog', 'companies'=>'building', 'products'=>'cube', 'commercial'=>'suitcase', 'invoicing'=>'coins', 'accounting'=>'chart-line', 'category'=>'tag', 'dollyrevert'=>'dolly', 'hrm'=>'user-tie', 'margin'=>'calculator', 'members'=>'user-friends', 'ticket'=>'ticket-alt', 'globe'=>'external-link-alt', 'lot'=>'barcode', - 'email'=>'at', + 'email'=>'at', 'establishment'=>'building', 'edit'=>'pencil-alt', 'grip_title'=>'arrows-alt', 'grip'=>'arrows-alt', 'help'=>'question-circle', 'generic'=>'file', 'holiday'=>'umbrella-beach', 'info'=>'info-circle', 'inventory'=>'boxes', 'intracommreport'=>'globe-europe', 'label'=>'layer-group', 'loan'=>'money-bill-alt', diff --git a/htdocs/hrm/admin/admin_establishment.php b/htdocs/hrm/admin/admin_establishment.php index eb61b7e7807..11e965dc1d3 100644 --- a/htdocs/hrm/admin/admin_establishment.php +++ b/htdocs/hrm/admin/admin_establishment.php @@ -27,6 +27,8 @@ require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'hrm')); +$permissiontoadd = $user->admin; + if (!$user->admin) { accessforbidden(); } @@ -73,11 +75,13 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("HRMSetup"), $linkback); +$newcardbutton = dolGetButtonTitle($langs->trans('NewEstablishment'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/hrm/establishment/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); + // Configuration header $head = hrm_admin_prepare_head(); -print dol_get_fiche_head($head, 'establishments', $langs->trans("HRM"), -1, "user"); +print dol_get_fiche_head($head, 'establishments', $langs->trans("HRM"), -1, "user", 0, $newcardbutton); -$sql = "SELECT e.rowid, e.label, e.address, e.zip, e.town, e.status"; +$sql = "SELECT e.rowid, e.rowid as ref, e.label, e.address, e.zip, e.town, e.status"; $sql .= " FROM ".MAIN_DB_PREFIX."establishment as e"; $sql .= " WHERE e.entity IN (".getEntity('establishment').')'; $sql .= $db->order($sortfield, $sortorder); @@ -135,11 +139,6 @@ if ($result) { print dol_get_fiche_end(); -// Buttons -print ''; - // End of page llxFooter(); $db->close(); diff --git a/htdocs/hrm/admin/admin_hrm.php b/htdocs/hrm/admin/admin_hrm.php index 0131539071a..09cccfed3db 100644 --- a/htdocs/hrm/admin/admin_hrm.php +++ b/htdocs/hrm/admin/admin_hrm.php @@ -27,10 +27,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'hrm')); -if (!$user->admin) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); // Other parameters HRM_* @@ -38,9 +34,15 @@ $list = array( // 'HRM_EMAIL_EXTERNAL_SERVICE' // To prevent your public accountant for example ); +if (!$user->admin) { + accessforbidden(); +} + + /* * Actions */ + if ($action == 'update') { $error = 0; diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php index bca81f2e45d..c63ab29a14a 100644 --- a/htdocs/hrm/class/establishment.class.php +++ b/htdocs/hrm/class/establishment.class.php @@ -58,7 +58,7 @@ class Establishment extends CommonObject /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png */ - public $picto = 'building'; + public $picto = 'establishment'; /** * @var int ID @@ -428,34 +428,92 @@ class Establishment extends CommonObject } /** - * Return clicable name (with picto eventually) + * Return a link to the object card (with optionaly the picto) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @return string String with URL + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL */ - public function getNomUrl($withpicto = 0) + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) { - global $langs; + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) { + $notooltip = 1; // Force disable tooltips + } $result = ''; - $link = ''; - $linkend = ''; + $label = img_picto('', $this->picto).' '.$langs->trans("Establishment").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; - $picto = 'building'; + $url = DOL_URL_ROOT.'/hrm/establishment/card.php?id='.$this->id; - $label = ''.$langs->trans("Establishment").''; - $label .= '
'.$langs->trans("Label").': '.$this->label; + if ($option != 'nolink') { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { + $add_save_lastsearch_values = 1; + } + if ($add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } + } + + $linkclose = ''; + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $label = $langs->trans("Establishment"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } + + if ($option == 'nolink') { + $linkstart = ''; + if ($option == 'nolink') { + $linkend = ''; + } else { + $linkend = ''; + } + + $result .= $linkstart; if ($withpicto) { - $result .= ($link.img_object($label, $picto).$linkend); - } - if ($withpicto && $withpicto != 2) { - $result .= ' '; + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); } + if ($withpicto != 2) { - $result .= $link.$this->label.$linkend; + $result .= $this->ref; } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('establishmentdao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } + return $result; } diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php index 96874db6504..b2f477b48e5 100644 --- a/htdocs/hrm/establishment/card.php +++ b/htdocs/hrm/establishment/card.php @@ -19,6 +19,7 @@ * \file htdocs/hrm/establishment/card.php * \brief Page to show an establishment */ + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php'; require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php'; @@ -28,11 +29,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'hrm')); -// Security check -if (!$user->admin) { - accessforbidden(); -} - $error = 0; $action = GETPOST('action', 'aZ09'); @@ -55,6 +51,22 @@ $object = new Establishment($db); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once +$permissiontoadd = $user->rights->hrm->write; // Used by the include of actions_addupdatedelete.inc.php +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1]; + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +//restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', 0); +//if (empty($conf->mymodule->enabled)) accessforbidden(); +//if (empty($permissiontoread)) accessforbidden(); + +// Security check +if (!$user->admin) { + accessforbidden(); +} + /* * Actions @@ -165,7 +177,7 @@ if ($action == 'create') { // Name print '
'; print ''; - print ''; + print ''; print ''; // Entity @@ -252,7 +264,7 @@ if (($id || $ref) && $action == 'edit') { $head = establishment_prepare_head($object); if ($action == 'edit') { - print dol_get_fiche_head($head, 'card', $langs->trans("Establishment"), 0, 'building'); + print dol_get_fiche_head($head, 'card', $langs->trans("Establishment"), 0, $object->picto); print ''."\n"; print ''; @@ -335,7 +347,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $res = $object->fetch_optionals(); $head = establishment_prepare_head($object); - print dol_get_fiche_head($head, 'card', $langs->trans("Establishment"), -1, 'building'); + print dol_get_fiche_head($head, 'card', $langs->trans("Establishment"), -1, $object->picto); // Confirmation to delete if ($action == 'delete') { diff --git a/htdocs/hrm/establishment/info.php b/htdocs/hrm/establishment/info.php index f72b381a2d8..cff38ac7f42 100644 --- a/htdocs/hrm/establishment/info.php +++ b/htdocs/hrm/establishment/info.php @@ -76,12 +76,18 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->hrm->multidir_output[$object->entity]."/".$object->id; } +$permissiontoadd = $user->rights->hrm->write; // Used by the include of actions_addupdatedelete.inc.php +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1]; + // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; //$result = restrictedArea($user, 'mymodule', $object->id); -$permissiontoadd = $user->rights->hrm->write; // Used by the include of actions_addupdatedelete.inc.php +// Security check +if (!$user->admin) { + accessforbidden(); +} /* @@ -128,7 +134,7 @@ if ($object->id > 0) { $head = establishment_prepare_head($object); - print dol_get_fiche_head($head, 'info', $langs->trans("Establishment"), -1, 'building'); + print dol_get_fiche_head($head, 'info', $langs->trans("Establishment"), -1, $object->picto); // Object card // ------------------------------------------------------------ diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 76131c70719..fe4cd496df0 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -132,7 +132,7 @@ $upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object- // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; -//$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0); +//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', $isdraft); //if (empty($conf->mymodule->enabled)) accessforbidden(); //if (empty($permissiontoread)) accessforbidden(); From d5bab315e3c83dbe6fe26aaec223ce292d37542c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 15:03:18 +0100 Subject: [PATCH 205/207] FIX #yogosha5738 --- htdocs/hrm/admin/admin_establishment.php | 15 ++++++++++----- htdocs/hrm/admin/admin_hrm.php | 13 ++++++++++--- htdocs/hrm/establishment/card.php | 12 ++++-------- htdocs/hrm/establishment/info.php | 11 +++++------ htdocs/hrm/index.html | 0 5 files changed, 29 insertions(+), 22 deletions(-) delete mode 100644 htdocs/hrm/index.html diff --git a/htdocs/hrm/admin/admin_establishment.php b/htdocs/hrm/admin/admin_establishment.php index 11e965dc1d3..2772137284b 100644 --- a/htdocs/hrm/admin/admin_establishment.php +++ b/htdocs/hrm/admin/admin_establishment.php @@ -27,13 +27,18 @@ require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'hrm')); +$error = 0; + +$permissiontoread = $user->admin; $permissiontoadd = $user->admin; -if (!$user->admin) { - accessforbidden(); -} - -$error = 0; +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +//restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', 0); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (empty($permissiontoread)) accessforbidden(); /* diff --git a/htdocs/hrm/admin/admin_hrm.php b/htdocs/hrm/admin/admin_hrm.php index 09cccfed3db..d19b15e3499 100644 --- a/htdocs/hrm/admin/admin_hrm.php +++ b/htdocs/hrm/admin/admin_hrm.php @@ -34,9 +34,16 @@ $list = array( // 'HRM_EMAIL_EXTERNAL_SERVICE' // To prevent your public accountant for example ); -if (!$user->admin) { - accessforbidden(); -} +$permissiontoread = $user->admin; +$permissiontoadd = $user->admin; + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +//restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', 0); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (empty($permissiontoread)) accessforbidden(); /* diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php index b2f477b48e5..caec6191d0d 100644 --- a/htdocs/hrm/establishment/card.php +++ b/htdocs/hrm/establishment/card.php @@ -51,7 +51,8 @@ $object = new Establishment($db); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once -$permissiontoadd = $user->rights->hrm->write; // Used by the include of actions_addupdatedelete.inc.php +$permissiontoread = $user->admin; +$permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php $upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1]; // Security check - Protection if external user @@ -59,13 +60,8 @@ $upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->enti //if ($user->socid > 0) $socid = $user->socid; //$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', 0); -//if (empty($conf->mymodule->enabled)) accessforbidden(); -//if (empty($permissiontoread)) accessforbidden(); - -// Security check -if (!$user->admin) { - accessforbidden(); -} +if (empty($conf->hrm->enabled)) accessforbidden(); +if (empty($permissiontoread)) accessforbidden(); /* diff --git a/htdocs/hrm/establishment/info.php b/htdocs/hrm/establishment/info.php index cff38ac7f42..517b76de93a 100644 --- a/htdocs/hrm/establishment/info.php +++ b/htdocs/hrm/establishment/info.php @@ -76,18 +76,17 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->hrm->multidir_output[$object->entity]."/".$object->id; } +$permissiontoread = $user->admin; $permissiontoadd = $user->rights->hrm->write; // Used by the include of actions_addupdatedelete.inc.php $upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1]; // Security check - Protection if external user //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; -//$result = restrictedArea($user, 'mymodule', $object->id); - -// Security check -if (!$user->admin) { - accessforbidden(); -} +//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +//restrictedArea($user, $object->element, $object->id, '', '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (empty($permissiontoread)) accessforbidden(); /* diff --git a/htdocs/hrm/index.html b/htdocs/hrm/index.html deleted file mode 100644 index e69de29bb2d..00000000000 From a2c2d46e5c4ca4ea561f05b0374bdc9bfe58bbcd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 15:22:48 +0100 Subject: [PATCH 206/207] Fix loosing html content in edit --- htdocs/externalsite/admin/index.php | 9 +++++++-- htdocs/langs/en_US/externalsite.lang | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/htdocs/externalsite/admin/index.php b/htdocs/externalsite/admin/index.php index 1710a570c45..a9a41c5e555 100644 --- a/htdocs/externalsite/admin/index.php +++ b/htdocs/externalsite/admin/index.php @@ -58,7 +58,7 @@ if ($action == 'update') { $exturl = GETPOST('EXTERNALSITE_URL', 'none'); $exturl = dol_string_onlythesehtmltags($exturl, 1, 1, 0, 1); - $exturl = dol_string_onlythesehtmlattributes($exturl); + $exturl = trim(dol_string_onlythesehtmlattributes($exturl)); $i += dolibarr_set_const($db, 'EXTERNALSITE_LABEL', trim($label), 'chaine', 0, '', $conf->entity); $i += dolibarr_set_const($db, 'EXTERNALSITE_URL', trim($exturl), 'chaine', 0, '', $conf->entity); @@ -108,7 +108,12 @@ print ""; print ''; print '"; print ''; print "'; print ''; print ''; } @@ -1122,12 +1122,12 @@ if ($action == 'create') { if (!empty($product->status_batch)) { print ''; if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { - print ''; } if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - print ''; } @@ -1798,7 +1798,7 @@ if ($action == 'create') { print ''; // Batch number managment if ($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch)) { - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print ''; + print ''; print ''.$objp->ref.''.$objp->ref_client.''; if ($possiblelink['label'] == 'LinkToContract') { $form = new Form($this->db); print $form->textwithpicto('', $langs->trans("InformationOnLinkToContract")).' '; } - print price($objp->total_ht).''.$objp->name.'
'.price($obj->total_ht)."'.price($obj->total_ht)."'.price($obj->total_tva)."'.price($obj->total_tva)."'.price($obj->total_ttc)."'.price($obj->total_ttc)."'.price($totalInvoicedHT)."'.price($totalInvoicedHT)."'.price($totalInvoicedTTC)."'.price($totalInvoicedTTC)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_tva)."'.price($obj->multicurrency_total_tva)."'.price($obj->multicurrency_total_ttc)."'.price($obj->multicurrency_total_ttc)."'.price($multicurrency_totalInvoicedHT)."'.price($multicurrency_totalInvoicedHT)."'.price($multicurrency_totalInvoicedTTC)."'.price($multicurrency_totalInvoicedTTC)."'.price($obj->total_ht)."'.price($obj->total_ht)."'.price($obj->total_tva)."'.price($obj->total_tva)."'.price($obj->total_ttc)."'.price($obj->total_ttc)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_ttc)."'.price($obj->multicurrency_total_ttc)."'.price($obj->total_ht)."'.price($obj->total_ht)."'.price($obj->total_tva)."'.price($obj->total_tva)."'.price($obj->total_ttc)."'.price($obj->total_ttc)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_tva)."'.price($obj->multicurrency_total_tva)."'.price($obj->multicurrency_total_ttc)."'.price($obj->multicurrency_total_ttc)."'; //if ($obj->opp_status_code) if (strcmp($obj->opp_amount, '')) { - print price($obj->opp_amount, 1, $langs, 1, -1, -1, ''); + print ''.price($obj->opp_amount, 1, $langs, 1, -1, -1, '').''; $totalarray['val']['p.opp_amount'] += $obj->opp_amount; } print ''; if ($obj->opp_weighted_amount) { - print price($obj->opp_weighted_amount, 1, $langs, 1, -1, -1, ''); + print ''.price($obj->opp_weighted_amount, 1, $langs, 1, -1, -1, '').''; $totalarray['val']['opp_weighted_amount'] += $obj->opp_weighted_amount; } print ''; if ($obj->budget_amount != '') { - print price($obj->budget_amount, 1, $langs, 1, -1, -1); + print ''.price($obj->budget_amount, 1, $langs, 1, -1, -1).''; $totalarray['val']['p.budget_amount'] += $obj->budget_amount; } print ''; if ($obj->price_registration != '') { - print price($obj->price_registration, 1, $langs, 1, -1, -1); + print ''.price($obj->price_registration, 1, $langs, 1, -1, -1).''; $totalarray['val']['p.price_registration'] += $obj->price_registration; } print ''; if ($obj->price_booth != '') { - print price($obj->price_booth, 1, $langs, 1, -1, -1); + print ''.price($obj->price_booth, 1, $langs, 1, -1, -1).''; $totalarray['val']['p.price_booth'] += $obj->price_booth; } print ''.price($obj->total_ht)."'.price($obj->total_ht)."'.price($obj->total_tva)."'.price($obj->total_tva)."'.price($obj->total_ttc)."'.price($obj->total_ttc)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_ttc)."'.price($obj->multicurrency_total_ttc)."'.dol_print_phone($obj->phone_pro, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''.dol_print_phone($obj->phone_pro, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''.dol_print_phone($obj->phone_perso, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''.dol_print_phone($obj->phone_perso, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'phone').''.dol_print_phone($obj->phone_mobile, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'mobile').''.dol_print_phone($obj->phone_mobile, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'mobile').''.dol_print_phone($obj->fax, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'fax').''.dol_print_phone($obj->fax, $obj->country_code, $obj->rowid, $obj->socid, 'AC_TEL', ' ', 'fax').''.dol_print_email($obj->email, $obj->rowid, $obj->socid, 'AC_EMAIL', 18, 0, 1).''.dol_print_email($obj->email, $obj->rowid, $obj->socid, 'AC_EMAIL', 18, 0, 1).''; + print ''; if ($obj->socid) { $objsoc = new Societe($db); $objsoc->fetch($obj->socid); diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 47ef99490cb..74a04f34858 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -941,7 +941,8 @@ if (empty($type) || $type == 'c' || $type == 'p') { if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= img_picto('', 'category', 'class="pictofixedwidth"'); + $tmptitle = $langs->trans('Categories'); + $moreforfilter .= img_picto($tmptile, 'category', 'class="pictofixedwidth"'); $moreforfilter .= $formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1, $langs->trans('CustomersProspectsCategoriesShort')); $moreforfilter .= '
'; } @@ -950,7 +951,8 @@ if (empty($type) || $type == 'f') { if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $moreforfilter .= '
'; - $moreforfilter .= img_picto('', 'category', 'class="pictofixedwidth"'); + $tmptitle = $langs->trans('Categories'); + $moreforfilter .= img_picto($tmptilte, 'category', 'class="pictofixedwidth"'); $moreforfilter .= $formother->select_categories('supplier', $search_categ_sup, 'search_categ_sup', 1, $langs->trans('SuppliersCategoriesShort')); $moreforfilter .= '
'; } @@ -959,7 +961,8 @@ if (empty($type) || $type == 'f') { // If the user can view prospects other than his' if ($user->rights->societe->client->voir || $socid) { $moreforfilter .= '
'; - $moreforfilter .= img_picto('', 'user', 'class="pictofixedwidth"'); + $tmptile = $langs->trans('SalesRepresentatives'); + $moreforfilter .= img_picto($tmptile, 'user', 'class="pictofixedwidth"'); $moreforfilter .= $formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $langs->trans('SalesRepresentatives'), ($conf->dol_optimize_smallscreen ? 'maxwidth200' : 'maxwidth300'), 1); $moreforfilter .= '
'; } From 1d48b883a7152bb1fbca10cb993703e603b8df32 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 13:17:56 +0100 Subject: [PATCH 200/207] Look and feel v14 --- htdocs/core/class/html.form.class.php | 11 +++++++++-- htdocs/expedition/list.php | 24 +++++++++++++++--------- htdocs/product/list.php | 16 ++++++++-------- htdocs/product/stock/list.php | 16 +++++++++------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 21c886cb2fa..6139ad2b2fc 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1831,7 +1831,7 @@ class Form * * @param string $selected User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1, keep unselected (if empty is allowed) * @param string $htmlname Field name in form - * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list + * @param int|string $show_empty 0=list with no empty value, 1=add also an empty value into list * @param array $exclude Array list of users id to exclude * @param int $disabled If select list must be disabled * @param array|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me @@ -1949,7 +1949,14 @@ class Form // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined $out .= '
'; if ($obj->tosell) { if ($obj->price_base_type == 'TTC') { - print price($obj->price_ttc).' '.$langs->trans("TTC"); + print ''.price($obj->price_ttc).' '.$langs->trans("TTC").''; } else { - print price($obj->price).' '.$langs->trans("HT"); + print ''.price($obj->price).' '.$langs->trans("HT").''; } } print ''; if (!empty($productpricescache[$obj->rowid])) { if ($productpricescache[$obj->rowid][$key]['price_base_type'] == 'TTC') { - print price($productpricescache[$obj->rowid][$key]['price_ttc']).' '.$langs->trans("TTC"); + print ''.price($productpricescache[$obj->rowid][$key]['price_ttc']).' '.$langs->trans("TTC").''; } else { - print price($productpricescache[$obj->rowid][$key]['price']).' '.$langs->trans("HT"); + print ''.price($productpricescache[$obj->rowid][$key]['price']).' '.$langs->trans("HT").''; } } print ''; - print price($product_static->pmp, 1, $langs); + print ''.price($product_static->pmp, 1, $langs).""; print ''; //print $obj->cost_price; - print price($obj->cost_price).' '.$langs->trans("HT"); + print ''.price($obj->cost_price).' '.$langs->trans("HT").''; print ''; if (price2num($obj->estimatedvalue, 'MT')) { - print price(price2num($obj->estimatedvalue, 'MT'), 1); + print ''.price(price2num($obj->estimatedvalue, 'MT'), 1).''; } else { print ''; } @@ -650,7 +650,9 @@ if ($num) { if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) { print ''; if (empty($conf->global->PRODUIT_MULTIPRICES)) { - print price(price2num($obj->sellvalue, 'MT'), 1); + if ($obj->sellvalue) { + print ''.price(price2num($obj->sellvalue, 'MT'), 1).''; + } } else { $htmltext = $langs->trans("OptionMULTIPRICESIsOn"); print $form->textwithtooltip($langs->trans("Variable"), $htmltext); From 1bb07c0eb16e5bf736fe89ea14c99879d02fcd99 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 13:59:50 +0100 Subject: [PATCH 201/207] Look and feel v14 --- htdocs/admin/index.php | 2 +- htdocs/admin/modules.php | 16 ++++++++++------ htdocs/core/lib/admin.lib.php | 20 ++++++++++++++++---- htdocs/core/lib/functions.lib.php | 2 +- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index d94c8a3fffd..a97717412a9 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -93,7 +93,7 @@ print '
'; // Show info setup module print img_picto('', 'cog', 'class="paddingright"').' '.$langs->trans("SetupDescription4", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules")); -if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled +if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningEnableYourModulesApplications"), 'style="padding-right: 6px;"'); print '
'; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 5cf852fdacb..9b9fcdea1fd 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -463,11 +463,13 @@ asort($orders); //var_dump($modules); $nbofactivatedmodules = count($conf->modules); -$moreinfo = $langs->trans("TitleNumberOfActivatedModules"); + +//$conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING = 1000; +/*$moreinfo = $langs->trans("TitleNumberOfActivatedModules"); $moreinfo2 = ''.($nbofactivatedmodules - 1).' / '.count($modules).''; -if ($nbofactivatedmodules <= 1) { +if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { $moreinfo2 .= ' '.img_warning($langs->trans("YouMustEnableOneModule")); -} +}*/ print load_fiche_titre($langs->trans("ModulesSetup"), '', 'title_setup'); @@ -476,7 +478,9 @@ $deschelp = ''; if ($mode == 'common' || $mode == 'commonkanban') { $desc = $langs->trans("ModulesDesc", '{picto}'); $desc = str_replace('{picto}', img_picto('', 'switch_off'), $desc); - $deschelp = '
'.$desc."

\n"; + if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled + $deschelp = '
'.$desc."

\n"; + } } if ($mode == 'marketplace') { //$deschelp = '
'.$langs->trans("ModulesMarketPlaceDesc")."

\n"; @@ -488,7 +492,7 @@ if ($mode == 'develop') { $deschelp = '
'.$langs->trans("ModulesDevelopDesc")."

\n"; } -$head = modules_prepare_head(); +$head = modules_prepare_head($nbofactivatedmodules, count($modules)); if ($mode == 'common' || $mode == 'commonkanban') { @@ -521,7 +525,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.$param, '', 1, array('morecss'=>'reposition'.($mode == 'commonkanban' ? '' : ' btnTitleSelected'))); $moreforfilter .= ''; - $moreforfilter .= '
'.$moreinfo.' '.$moreinfo2.'
'; + //$moreforfilter .= '
'.$moreinfo.' '.$moreinfo2.'
'; $moreforfilter .= '
'; $moreforfilter .= '
'; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index d2c75082318..3088db079e3 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -635,16 +635,28 @@ function dolibarr_set_const($db, $name, $value, $type = 'chaine', $visible = 0, /** * Prepare array with list of tabs * - * @return array Array of tabs to show + * @param int $nbofactivatedmodules Number f oactivated modules + * @param int $nboftotalmodules Nb of total modules + * @return array Array of tabs to show */ -function modules_prepare_head() +function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules) { - global $langs, $conf, $user; + global $langs, $conf, $user, $form; + + $desc = $langs->trans("ModulesDesc", '{picto}'); + $desc = str_replace('{picto}', img_picto('', 'switch_off'), $desc); + $h = 0; $head = array(); $mode = empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : 'common'; $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$mode; - $head[$h][1] = $langs->trans("AvailableModules"); + if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled) + $head[$h][1] = $form->textwithpicto($langs->trans("AvailableModules"), $desc); + $head[$h][1] .= img_warning($langs->trans("YouMustEnableOneModule")); + } else { + //$head[$h][1] = $langs->trans("AvailableModules").$form->textwithpicto(''.$nbofactivatedmodules.' / '.$nboftotalmodules.'', $desc, 1, 'help', '', 1, 3); + $head[$h][1] = $langs->trans("AvailableModules").''.$nbofactivatedmodules.' / '.$nboftotalmodules.''; + } $head[$h][2] = 'modules'; $h++; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 26247a4d39e..082faa99865 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3535,7 +3535,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'label', 'language', 'link', 'list', 'listlight', 'loan', 'lot', 'long-arrow-alt-right', 'margin', 'map-marker-alt', 'member', 'meeting', 'money-bill-alt', 'movement', 'mrp', 'note', 'next', 'object_accounting', 'object_account', 'object_accountline', 'object_action', 'object_asset', 'object_barcode', 'object_bill', 'object_billr', 'object_billa', 'object_billd', 'object_bom', - 'object_category', 'conferenceorbooth', 'object_conversation', 'object_bookmark', 'object_bug', 'object_clock', 'object_dolly', 'object_dollyrevert', + 'object_category', 'conferenceorbooth', 'object_conversation', 'object_bookmark', 'object_bug', 'object_clock', 'object_collab', 'object_dolly', 'object_dollyrevert', 'object_folder', 'object_folder-open','object_generic', 'object_list-alt', 'object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser', 'object_cash-register', 'object_company', 'object_contact', 'object_contract', 'object_cron', 'object_donation', 'object_dynamicprice', From ef4f8fd585efa194815fcb3bcac2bdf5ef471e7c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 14:02:30 +0100 Subject: [PATCH 202/207] Lang --- htdocs/langs/en_US/boxes.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index 981b63500ac..4d7ee938c91 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -19,6 +19,7 @@ BoxLastContracts=Latest contracts BoxLastContacts=Latest contacts/addresses BoxLastMembers=Latest members BoxLastModifiedMembers=Latest modified members +BoxLastMembersSubscriptions=Latest member subscriptions BoxFicheInter=Latest interventions BoxCurrentAccounts=Open accounts balance BoxTitleMemberNextBirthdays=Birthdays of this month (members) From 5b64a517ea397d0715015d24b9dc74325121b177 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 14:30:10 +0100 Subject: [PATCH 203/207] Fix label --- htdocs/core/lib/project.lib.php | 2 +- htdocs/projet/tasks/list.php | 40 ++++++++++++++++----------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 8fef0916ff8..79e5e4f8dcc 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2554,7 +2554,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks $ponderated_opp_amount += price2num($opp_weighted_amount); } if ($objp->opp_amount) { - print ''.price($objp->opp_amount, 0, '', 1, -1, 0, $conf->currency).''; + print ''.price($objp->opp_amount, 0, '', 1, -1, 0, $conf->currency).''; } print '
'.$form->editfieldkey('Label', 'label', '', $object, 0, 'string', '', 1).'
'.$langs->trans("ExternalSiteURL")."http://localhost/myurl/"; print "
https://wikipedia.org/"; diff --git a/htdocs/langs/en_US/externalsite.lang b/htdocs/langs/en_US/externalsite.lang index da4853df0df..452100c65b3 100644 --- a/htdocs/langs/en_US/externalsite.lang +++ b/htdocs/langs/en_US/externalsite.lang @@ -1,5 +1,5 @@ # Dolibarr language file - Source file is en_US - externalsite ExternalSiteSetup=Setup link to external website -ExternalSiteURL=External Site URL +ExternalSiteURL=External Site URL of HTML iframe content ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly. ExampleMyMenuEntry=My menu entry From 4c90e931083c41b99a8e95905884d8ed57e0c564 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 27 Mar 2021 15:49:18 +0100 Subject: [PATCH 207/207] Fix permissions --- htdocs/reception/card.php | 46 ++++++++++++++++---------------- htdocs/reception/contact.php | 24 ++++++++++++----- htdocs/reception/index.php | 10 ++++++- htdocs/reception/list.php | 14 +++++----- htdocs/reception/note.php | 34 ++++++++++++----------- htdocs/reception/stats/index.php | 14 +++++----- htdocs/reception/stats/month.php | 6 +++++ 7 files changed, 88 insertions(+), 60 deletions(-) diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index bbfccb3b945..9392844adf2 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -86,25 +86,6 @@ if (empty($origin_id)) { $ref = GETPOST('ref', 'alpha'); $line_id = GETPOST('lineid', 'int') ?GETPOST('lineid', 'int') : ''; -// Security check -$socid = ''; -if ($user->socid) { - $socid = $user->socid; -} - -if ($origin == 'reception') { - $result = restrictedArea($user, $origin, $id); -} else { - $result = restrictedArea($user, 'reception'); - if ($origin == 'supplierorder') { - if (empty($user->rights->fournisseur->commande->lire) && empty($user->rights->fournisseur->commande->read)) { - accessforbidden(); - } - } elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) { - accessforbidden(); - } -} - $action = GETPOST('action', 'alpha'); //Select mail models is same action as presend if (GETPOST('modelselected')) { @@ -136,6 +117,25 @@ $permissiondellink = $user->rights->reception->creer; // Used by the include of $date_delivery = dol_mktime(GETPOST('date_deliveryhour', 'int'), GETPOST('date_deliverymin', 'int'), 0, GETPOST('date_deliverymonth', 'int'), GETPOST('date_deliveryday', 'int'), GETPOST('date_deliveryyear', 'int')); +// Security check +$socid = ''; +if ($user->socid) { + $socid = $user->socid; +} + +if ($origin == 'reception') { + $result = restrictedArea($user, $origin, $id); +} else { + $result = restrictedArea($user, 'reception'); + if ($origin == 'supplierorder') { + if (empty($user->rights->fournisseur->commande->lire) && empty($user->rights->fournisseur->commande->read)) { + accessforbidden(); + } + } elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) { + accessforbidden(); + } +} + /* * Actions @@ -784,7 +784,7 @@ if ($action == 'create') { print '
'.$langs->trans("Project").''; $numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid', 0); - print '   id).'">'.$langs->trans("AddProject").''; + print '   id).'">'; print '
'; + print ''; print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, '', '', 1, ""); print ''; + print ''; print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, '', '', 1, ""); print ''.$formproduct->selectWarehouses($lines[$i]->fk_entrepot, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'
'; + print '

'; if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { print $langs->trans('EatByDate').' : '; print $form->selectDate($lines[$i]->eatby, 'dlc'.$line_id, '', '', 1, "").'
'; diff --git a/htdocs/reception/contact.php b/htdocs/reception/contact.php index f814bbbf64a..f925388f0b6 100644 --- a/htdocs/reception/contact.php +++ b/htdocs/reception/contact.php @@ -43,12 +43,6 @@ $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'reception', $id, ''); - $object = new Reception($db); if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); @@ -69,6 +63,24 @@ if ($id > 0 || !empty($ref)) { } +// Security check +if ($user->socid > 0) { + $socid = $user->socid; +} +if ($origin == 'reception') { + $result = restrictedArea($user, $origin, $object->id); +} else { + $result = restrictedArea($user, 'reception'); + if ($origin == 'supplierorder') { + if (empty($user->rights->fournisseur->commande->lire) && empty($user->rights->fournisseur->commande->read)) { + accessforbidden(); + } + } elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) { + accessforbidden(); + } +} + + /* * Actions */ diff --git a/htdocs/reception/index.php b/htdocs/reception/index.php index 3aa6b8af754..a54eea592c0 100644 --- a/htdocs/reception/index.php +++ b/htdocs/reception/index.php @@ -36,13 +36,21 @@ $hookmanager->initHooks(array('receptionindex')); $langs->loadLangs(array("orders", "receptions")); +$reception = new Reception($db); + +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'reception', 0, ''); + + /* * View */ $orderstatic = new CommandeFournisseur($db); $companystatic = new Societe($db); -$reception = new Reception($db); $helpurl = 'EN:Module_Receptions|FR:Module_Receptions|ES:Módulo_Receptiones'; llxHeader('', $langs->trans("Reception"), $helpurl); diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index b77742dd71d..bdc65fb301b 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -40,13 +40,6 @@ $socid = GETPOST('socid', 'int'); $massaction = GETPOST('massaction', 'alpha'); $toselect = GETPOST('toselect', 'array'); -// Security check -$receptionid = GETPOST('id', 'int'); -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'reception', $receptionid, ''); - $diroutputmassaction = $conf->reception->dir_output.'/temp/massgeneration/'.$user->id; $search_ref_rcp = GETPOST("search_ref_rcp"); @@ -129,6 +122,13 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); $error = 0; +// Security check +$receptionid = GETPOST('id', 'int'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'reception', $receptionid, ''); + /* * Actions diff --git a/htdocs/reception/note.php b/htdocs/reception/note.php index b1588a07b14..a3a2b31589c 100644 --- a/htdocs/reception/note.php +++ b/htdocs/reception/note.php @@ -33,26 +33,12 @@ if (!empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; } -$langs->load("receptions"); -$langs->load("companies"); -$langs->load("bills"); -$langs->load('deliveries'); -$langs->load('orders'); -$langs->load('stocks'); -$langs->load('other'); -$langs->load('propal'); +$langs->loadLangs(array("receptions", "companies", "bills", 'deliveries', 'orders', 'stocks', 'other', 'propal')); $id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); -// Security check -$socid = ''; -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, $origin, $origin_id); - $object = new Reception($db); if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); @@ -77,6 +63,24 @@ if ($id > 0 || !empty($ref)) { $permissionnote = $user->rights->reception->creer; // Used by the include of actions_setnotes.inc.php +// Security check +if ($user->socid > 0) { + $socid = $user->socid; +} +if ($origin == 'reception') { + $result = restrictedArea($user, $origin, $object->id); +} else { + $result = restrictedArea($user, 'reception'); + if ($origin == 'supplierorder') { + if (empty($user->rights->fournisseur->commande->lire) && empty($user->rights->fournisseur->commande->read)) { + accessforbidden(); + } + } elseif (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) { + accessforbidden(); + } +} + + /* * Actions diff --git a/htdocs/reception/stats/index.php b/htdocs/reception/stats/index.php index 0b118c5d733..1fe3397ef66 100644 --- a/htdocs/reception/stats/index.php +++ b/htdocs/reception/stats/index.php @@ -34,11 +34,6 @@ $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height'); $userid = GETPOST('userid', 'int'); $socid = GETPOST('socid', 'int'); -// Security check -if ($user->socid > 0) { - $action = ''; - $socid = $user->socid; -} $nowyear = strftime("%Y", dol_now()); $year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; @@ -46,10 +41,13 @@ $year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; $startyear = $year - 1; $endyear = $year; -$langs->load("reception"); -$langs->load("other"); -$langs->load("companies"); +$langs->loadLangs(array("reception", "other", "companies")); +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'reception', 0, ''); /* diff --git a/htdocs/reception/stats/month.php b/htdocs/reception/stats/month.php index 25c6b16e116..806006394df 100644 --- a/htdocs/reception/stats/month.php +++ b/htdocs/reception/stats/month.php @@ -29,6 +29,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $year = GETPOST("year", 'int'); +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'reception', 0, ''); + /* * View