diff --git a/.mailmap b/.mailmap index ae4b0eb7146..f5486ee8634 100644 --- a/.mailmap +++ b/.mailmap @@ -89,3 +89,9 @@ Baffir Abbes bafbes GUERRIER Kevin Remy Younes remy Estephe Loridan Estephe L. +Anthony Berton Anthony Berton +Anthony Berton Berton Anthony +Anthony Berton BB2A-Anthony +Anthony Berton Anthony Berton +Anthony Berton Berton Anthony +Anthony Berton BB2A-Anthony \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1f4fc328a49..6cb27e2307f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,6 +53,10 @@ addons: - php8.1-mysqli - php8.1-xml - php8.1-intl + - php8.2-pgsql + - php8.2-mysqli + - php8.2-xml + - php8.2-intl env: global: @@ -73,8 +77,8 @@ jobs: php: '8.1' env: DB=mysql - stage: PHP Dev - if: type = push AND branch = 17.0 - php: nightly + if: type = push AND branch = developdisabled + php: '8.2' env: DB=mysql notifications: @@ -120,7 +124,7 @@ install: squizlabs/php_codesniffer ^3 fi # phpunit 9 is required for php 8 - if [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then + if [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = '8.2' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then composer self-update 2.4.4 composer -n require --ignore-platform-reqs phpunit/phpunit ^8 \ php-parallel-lint/php-parallel-lint ^1.2 \ @@ -260,7 +264,7 @@ before_script: # enable php-fpm - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf - | - if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then + if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = '8.2' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then # Copy the included pool sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf fi diff --git a/COPYRIGHT b/COPYRIGHT index 93f4a43fee1..eb4176aef19 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -29,7 +29,7 @@ GeoIP2 0.2.0 Apache License 2.0 Yes Mobiledetect 2.8.41 MIT License Yes Detect mobile devices browsers NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency -ParseDown 1.6 MIT License Yes Markdown parser +ParseDown 1.7.4 MIT License Yes Markdown parser PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files PHPDebugBar 1.18.2 MIT License Yes Used only by the module "debugbar" for developers PHP-Imap 2.7.2 MIT License Yes Library to use IMAP with OAuth @@ -43,7 +43,7 @@ Restler 3.1.1 LGPL-3+ Yes Sabre 3.2.2 BSD Yes DAV support Swift Mailer 5.4.2-DEV MIT License Yes Comprehensive mailing tools for PHP Symfony/var-dumper ??? MIT License Yes Library to make var dump (used by DebugBar) -Stripe 7.67.0 MIT Licence Yes Library for Stripe module +Stripe 10.7.0 MIT Licence Yes Library for Stripe module TCPDF 6.3.2 LGPL-3+ Yes PDF generation TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement diff --git a/ChangeLog b/ChangeLog index ce8c34636f6..5a34a51b738 100644 --- a/ChangeLog +++ b/ChangeLog @@ -269,18 +269,21 @@ WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * Minimal PHP version is now PHP 7.0 instead of PHP 5.6 +* Core has introduced a Universal Filter Syntax for seach criteria. Example: ((((field1:=:value1) OR (field2:in:1,2,3)) AND ...). In rare case, some filters + could be provided by URL parameters. For such cases (societe/ajax/company.php), use of Universal Filter Syntax become mandatory. * The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product->getNomUrl() * Trigger ORDER_SUPPLIER_DISPATCH is removed, use ORDER_SUPPLIER_RECEIVE and/or LINEORDER_SUPPLIER_DISPATCH instead. * All functions fetch_all() have been set to deprecated for naming consitency, use fetchAll() instead. * Code standardization: '$user->rights->propale' is now '$user->rights->propal' everywhere. * Deprecated method set_billed() on shipment and reception class has been removed. Use setBilled() instead. * Tables llx_prelevement_facture and llx_prelevement_facture_demande have been renamed into llx_prelevement and llx_prelevement_demande. -* Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES -* Rename the substitution for "project label" instead of "project title" in substitution variables -* You must use "$objectoffield" to manipulate the current object inside the formulare of computed custom extrafields instead of $obj/$object. +* Renamed MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and renamed MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES +* Renamed the substitution for "project label" instead of "project title" in substitution variables +* You must use "$objectoffield" to manipulate the current object inside the form of computed custom extrafields instead of $obj/$object. * Making a global search is sending the parameter using always the name search_all (instead of sometimes sall and search_all) * The property $url_last_version must be public if defined into module descriptor files; + ***** ChangeLog for 16.0.5 compared to 16.0.4 ***** FIX: 16.0 propalestats Unknown column 'p.fk_soc' in 'on clause' diff --git a/SECURITY.md b/SECURITY.md index 3c89a2f38e1..1c281099885 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,8 +6,8 @@ This file contains some policies about the security reports on Dolibarr ERP CRM | Version | Supported | | ---------- | ---------------------- | -| <= 16.0.2 | :x: | -| >= 16.0.3 | :white_check_mark: | +| <= 17.0.0 | :x: | +| >= 17.0.1 | :white_check_mark: | | >= develop | :white_check_mark: | ## Reporting a Vulnerability diff --git a/build/debian/rules b/build/debian/rules index b63fcffde93..df6abfd1b89 100755 --- a/build/debian/rules +++ b/build/debian/rules @@ -19,6 +19,10 @@ override_dh_auto_clean: override_dh_auto_build: # Do nothing. Added to disable launchpad to use bugged dh_auto_build search for ant +# Force the compression format for control files +override_dh_builddeb: + dh_builddeb -- -Zxz + #override_dh_compress: # dh_compress --no-act -X.png @@ -124,4 +128,4 @@ override_dh_fixperms: # Give rights to the webserver on the upload directory chown www-data:www-data debian/dolibarr/var/lib/dolibarr/documents chmod 2775 debian/dolibarr/var/lib/dolibarr/documents - + diff --git a/build/debian/source/options b/build/debian/source/options index 8d8fd181896..49a59df5428 100644 --- a/build/debian/source/options +++ b/build/debian/source/options @@ -1,3 +1,5 @@ -# Force use of gzip compression by dpkg-buildpackage +# Force use of gzip compression by dpkg-buildpackage for the tarball *.debian.tar.gz +# See also option --compression from command line of dpkg-buildpackage +# Format for the control files are defined into the rules file in override_dh_builddeb section compression = "gzip" #compression-level = 9 diff --git a/build/doxygen/dolibarr-doxygen.doxyfile b/build/doxygen/dolibarr-doxygen.doxyfile index 6f668ebad7e..2bcb32a1540 100644 --- a/build/doxygen/dolibarr-doxygen.doxyfile +++ b/build/doxygen/dolibarr-doxygen.doxyfile @@ -220,7 +220,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = example=PHP # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should @@ -602,7 +602,7 @@ INPUT_ENCODING = UTF-8 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.php *.pl +FILE_PATTERNS = *.php *.pl *.sql *.example # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. diff --git a/build/exe/doliwamp/Languages/MyCatalan.isl b/build/exe/doliwamp/Languages/MyCatalan.isl index b157d1cea27..cb1066b5f91 100644 --- a/build/exe/doliwamp/Languages/MyCatalan.isl +++ b/build/exe/doliwamp/Languages/MyCatalan.isl @@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=L'instal·lador DoliWamp intentarà iniciar o reini OldVersionFoundAndMoveInNew=S'ha trobat una versió antiga de base de dades i ha estat moguda per a ser utilitzada per la nova versió de Dolibarr OldVersionFoundButFailedToMoveInNew=S'ha trobat una versió antiga de base de dades, però no es pot moure per a ser utilitzada per la nova versió de Dolibarr -DLLMissing=La teva instal·lació windows no té el component "Microsoft Visual C++ Redistributable for Visual Studio 2012". Instal·la primer la versió de 32-bit (vcredist_x86.exe) (pots trobar-la a https://www.microsoft.com/en-us/download/) i reiniciar després la instal·lació/actualització de DoliWamp. +DLLMissing=La teva instal·lació windows no té el component "Microsoft Visual C++ Redistributable for Visual Studio 2015". Instal·la primer la versió de 32-bit (vcredist_x86.exe) (pots trobar-la a https://www.microsoft.com/en-us/download/) i reiniciar després la instal·lació/actualització de DoliWamp. ContinueAnyway=Continua igualment (el procés d'instal·lació podria fallar sense aquest prerequisit) diff --git a/build/exe/doliwamp/Languages/MyEnglish.isl b/build/exe/doliwamp/Languages/MyEnglish.isl index 9c91ae92e4a..2a6c8b9a4ba 100644 --- a/build/exe/doliwamp/Languages/MyEnglish.isl +++ b/build/exe/doliwamp/Languages/MyEnglish.isl @@ -44,5 +44,5 @@ DoliWampWillStartApacheMysql=DoliWamp installer will now start or restart Apache OldVersionFoundAndMoveInNew=An old database version has been found and moved to be used by the new Dolibarr version OldVersionFoundButFailedToMoveInNew=An old database version has been found but could not be moved to be used with the new Dolibarr version -DLLMissing=Your Windows installation is missing the "Microsoft Visual C++ Redistributable for Visual Studio 2012" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after. +DLLMissing=Your Windows installation is missing The "Microsoft Visual C++ Redistributable for Visual Studio 2015" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after. ContinueAnyway=Continue anyway (install process may fail without this prerequisite) diff --git a/build/exe/doliwamp/Languages/MyFrench.isl b/build/exe/doliwamp/Languages/MyFrench.isl index c3fd15cbac8..6c6294fb7c4 100644 --- a/build/exe/doliwamp/Languages/MyFrench.isl +++ b/build/exe/doliwamp/Languages/MyFrench.isl @@ -44,5 +44,5 @@ DoliWampWillStartApacheMysql=L'installeur DoliWamp va maintenant d OldVersionFoundAndMoveInNew=Une ancienne version de base a t trouve et dplace pour fonctionner avec la nouvelle version de Dolibarr. OldVersionFoundButFailedToMoveInNew=Une ancienne version de base a t trouve mais ne peut tre dplace pour tre utilise avec la nouvelle version de Dolibarr. -DLLMissing=L'installation de votre Windows est incomplte. Il manque le composant "Micrsoft Visual C++ Redistributable for Visual Studio 2012". Installer la version 32-bit (vcredist_x86.exe) d'abord (vous pourrez le trouver https://www.microsoft.com/fr-fr/download/) puis relancer l'installation de DoliWamp aprs. +DLLMissing=L'installation de votre Windows est incomplte. Il manque le composant "Micrsoft Visual C++ Redistributable for Visual Studio 2015". Installer la version 32-bit (vcredist_x86.exe) d'abord (vous pourrez le trouver https://www.microsoft.com/fr-fr/download/) puis relancer l'installation de DoliWamp aprs. ContinueAnyway=Continuer malgr tout (le process d'installaton chouera) diff --git a/build/exe/doliwamp/Languages/MyGerman.isl b/build/exe/doliwamp/Languages/MyGerman.isl index 8bfd78dbea2..132260b7273 100644 --- a/build/exe/doliwamp/Languages/MyGerman.isl +++ b/build/exe/doliwamp/Languages/MyGerman.isl @@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=Die DoliWamp-Installation wird nun starten oder Apa OldVersionFoundAndMoveInNew=Eine alte Datenbankversion wurde gefunden und verschoben, um von der neuen Dolibarr-Version verwendet zu werden. OldVersionFoundButFailedToMoveInNew=Eine alte Datenbankversion wurde gefunden, konnte jedoch nicht verschoben werden, um mit der neuen Dolibarr-Version verwendet zu werden. -DLLMissing=Your Windows installation is missing The "Micrsoft Visual C++ Redistributable for Visual Studio 2012" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after. +DLLMissing=Your Windows installation is missing The "Micrsoft Visual C++ Redistributable for Visual Studio 2015" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after. ContinueAnyway=Fahren Sie trotzdem fort (der Installationsvorgang kann ohne diese Voraussetzung fehlschlagen). diff --git a/build/exe/doliwamp/Languages/MySpanish.isl b/build/exe/doliwamp/Languages/MySpanish.isl index c31aedf895f..6880a9263e1 100644 --- a/build/exe/doliwamp/Languages/MySpanish.isl +++ b/build/exe/doliwamp/Languages/MySpanish.isl @@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=El instalador DoliWamp intentará iniciar o reinici OldVersionFoundAndMoveInNew=Se ha encontrado una versión antigua de base de datos y ha sido movida para ser utilizada por la nueva versión de Dolibarr OldVersionFoundButFailedToMoveInNew=Se ha encontrado una versión antigua de base de datos, pero no se pudo mover para ser utilizada por la nueva versión de Dolibarr -DLLMissing=Su instalación Windows no tiene el componente "Microsoft Visual C++ Redistributable for Visual Studio 2012". Instale primero la versión de 32-bit (vcredist_x86.exe) (puedes encontrarlo en https://www.microsoft.com/en-us/download/) y reiniciar después la instalación/actualización de DoliWamp. +DLLMissing=Su instalación Windows no tiene el componente "Microsoft Visual C++ Redistributable for Visual Studio 2015". Instale primero la versión de 32-bit (vcredist_x86.exe) (puedes encontrarlo en https://www.microsoft.com/en-us/download/) y reiniciar después la instalación/actualización de DoliWamp. ContinueAnyway=Continua igualmente (el proceso de instalación podría fallar sin este prerequisito) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index f0433da142b..b7586e3909f 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -1050,16 +1050,16 @@ if ($nboftargetok) { print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"); #$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; - $cmd="dpkg-buildpackage -us -uc"; + $cmd="dpkg-buildpackage -us -uc --compression=gzip"; print "Launch DEB build ($cmd)\n"; $ret=`$cmd 2>&1 3>&1`; print $ret."\n"; chdir("$olddir"); - + print "You can check bin package with lintian --pedantic -E -I \"$NEWDESTI/${FILENAMEDEB}_all.deb\"\n"; print "You can check src package with lintian --pedantic -E -I \"$NEWDESTI/${FILENAMEDEB}.dsc\"\n"; - + # Move to final dir print "Move *_all.deb *.dsc *.orig.tar.gz *.changes to $NEWDESTI\n"; $ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`; diff --git a/build/makepack-howto.txt b/build/makepack-howto.txt index 7bc42a0bf88..184022ecf18 100644 --- a/build/makepack-howto.txt +++ b/build/makepack-howto.txt @@ -27,12 +27,12 @@ Prerequisites to build autoexe DoliWamp package from Linux (solution seems broke Prerequisites to build autoexe DoliWamp package from Windows: -> Install Perl for Windwos (https://strawberryperl.com/) +> Install Perl for Windows (https://strawberryperl.com/) > Install isetup-5.5.8.exe (https://www.jrsoftware.org) > Install WampServer-3.2.*-64.exe (Apache 2.4.51, PHP 7.3.33, MariaDB 10.6.5 for example. Version must match the values found into doliwamp.iss) > Install GIT for Windows (https://git-scm.com/ => You must choose option "Add Git bash profile", "Git commit as-is") -> Install Dolibarr verions: - git clone https://github.com/dolibarr/dolibarr +> Install Dolibarr current version: + git clone https://github.com/dolibarr/dolibarr or git clone --branch X.Y https://github.com/dolibarr/dolibarr > Add the path of PHP (C:\wamp64\bin\php\php7.3.33) and InnoSetup (C:\Program Files (x86)\Inno Setup 5) into the %PATH% of Windows. diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 91b7673ab81..324f5d8d447 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -321,7 +321,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_account) { $param .= '&search_account='.urlencode($search_account); diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 2bd1037db39..13a07be6dfc 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2020 Alexandre Spangaro + * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -81,6 +81,10 @@ $list_account[] = '---Others---'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; +if (!empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) { + $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT'; + $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT'; +} if (isModEnabled('banque')) { $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; } diff --git a/htdocs/accountancy/admin/fiscalyear.php b/htdocs/accountancy/admin/fiscalyear.php index 27226d388f6..82cf7d282f1 100644 --- a/htdocs/accountancy/admin/fiscalyear.php +++ b/htdocs/accountancy/admin/fiscalyear.php @@ -97,7 +97,7 @@ $help_url = "EN:Module_Double_Entry_Accounting"; llxHeader('', $title, $help_url); -$sql = "SELECT f.rowid, f.label, f.date_start, f.date_end, f.statut, f.entity"; +$sql = "SELECT f.rowid, f.label, f.date_start, f.date_end, f.statut as status, f.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."accounting_fiscalyear as f"; $sql .= " WHERE f.entity = ".$conf->entity; $sql .= $db->order($sortfield, $sortorder); @@ -137,14 +137,19 @@ if ($result) { print ''.$langs->trans("DateEnd").''; print ''.$langs->trans("NumberOfAccountancyEntries").''; print ''.$langs->trans("NumberOfAccountancyMovements").''; - print ''.$langs->trans("Statut").''; + print ''.$langs->trans("Status").''; print ''; if ($num) { while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); + $fiscalyearstatic->ref = $obj->rowid; $fiscalyearstatic->id = $obj->rowid; + $fiscalyearstatic->date_start = $obj->date_start; + $fiscalyearstatic->date_end = $obj->date_end; + $fiscalyearstatic->statut = $obj->status; + $fiscalyearstatic->status = $obj->status; print ''; print ''; @@ -155,7 +160,7 @@ if ($result) { print ''.dol_print_date($db->jdate($obj->date_end), 'day').''; print ''.$object->getAccountancyEntriesByFiscalYear($obj->date_start, $obj->date_end).''; print ''.$object->getAccountancyMovementsByFiscalYear($obj->date_start, $obj->date_end).''; - print ''.$fiscalyearstatic->LibStatut($obj->statut, 5).''; + print ''.$fiscalyearstatic->LibStatut($obj->status, 5).''; print ''; $i++; } diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 3a7be3e073e..174d8fdf13e 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -66,12 +66,7 @@ $error = 0; * Actions */ -if (in_array($action, array( - 'setBANK_DISABLE_DIRECT_INPUT', - 'setACCOUNTANCY_COMBO_FOR_AUX', - 'setACCOUNTING_MANAGE_ZERO', - 'setACCOUNTING_LIST_SORT_VENTILATION_TODO', - 'setACCOUNTING_LIST_SORT_VENTILATION_DONE'))) { +if (in_array($action, array('setBANK_DISABLE_DIRECT_INPUT', 'setACCOUNTANCY_COMBO_FOR_AUX', 'setACCOUNTING_MANAGE_ZERO'))) { $constname = preg_replace('/^set/', '', $action); $constvalue = GETPOST('value', 'int'); $res = dolibarr_set_const($db, $constname, $constvalue, 'yesno', 0, '', $conf->entity); @@ -121,34 +116,6 @@ if ($action == 'update') { } } -if ($action == 'setlistsorttodo') { - $setlistsorttodo = GETPOST('value', 'int'); - $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $setlistsorttodo, 'yesno', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - - if (!$error) { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("Error"), null, 'mesgs'); - } -} - -if ($action == 'setlistsortdone') { - $setlistsortdone = GETPOST('value', 'int'); - $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_DONE", $setlistsortdone, 'yesno', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - - if (!$error) { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("Error"), null, 'mesgs'); - } -} - if ($action == 'setmanagezero') { $setmanagezero = GETPOST('value', 'int'); $res = dolibarr_set_const($db, "ACCOUNTING_MANAGE_ZERO", $setmanagezero, 'yesno', 0, '', $conf->entity); @@ -275,6 +242,19 @@ if ($action == 'setenableautolettering') { } } +if ($action == 'setenablevatreversecharge') { + $setenablevatreversecharge = GETPOST('value', 'int'); + $res = dolibarr_set_const($db, "ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE", $setenablevatreversecharge, 'yesno', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'mesgs'); + } +} /* * View @@ -404,33 +384,6 @@ print ''; print ''.$langs->trans('BindingOptions').''; print "\n"; -// TO DO Mutualize code for yes/no constants -print ''; -print ''.$langs->trans("ACCOUNTING_LIST_SORT_VENTILATION_TODO").''; -if (!empty($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO)) { - print ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - print ''; -} else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print ''; -} -print ''; - -print ''; -print ''.$langs->trans("ACCOUNTING_LIST_SORT_VENTILATION_DONE").''; -if (!empty($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_DONE)) { - print ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - print ''; -} else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print ''; -} -print ''; - // Param a user $user->rights->accounting->chartofaccount can access foreach ($list_binding as $key) { print ''; @@ -495,14 +448,20 @@ print ''; print ''; print '
'; -// Lettering params + +// Show advanced options +print '
'; + + +// Advanced params print ''; print ''; -print ''; +print ''; print "\n"; print ''; -print ''; +print ''; if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { print ''; if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { print ''; - print ''; + print ''; if (!empty($conf->global->ACCOUNTING_ENABLE_AUTOLETTERING)) { print ''; } +print ''; +print ''; +if (!empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) { + print ''; +} else { + print ''; +} +print ''; + print '
'.$langs->trans('Options').' '.$langs->trans('Lettering').'' . $langs->trans('OptionsAdvanced') . '
'.$langs->trans("ACCOUNTING_ENABLE_LETTERING").''; +print $form->textwithpicto($langs->trans("ACCOUNTING_ENABLE_LETTERING"), $langs->trans("ACCOUNTING_ENABLE_LETTERING_DESC", $langs->transnoentitiesnoconv("NumMvts")).'
'.$langs->trans("EnablingThisFeatureIsNotNecessary")).'
'; print img_picto($langs->trans("Activated"), 'switch_on'); @@ -516,7 +475,8 @@ print '
' . $langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING") . ''; + print $form->textwithpicto($langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING"), $langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING_DESC")) . ''; print img_picto($langs->trans("Activated"), 'switch_on'); @@ -529,8 +489,23 @@ if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { print '
'; +print $form->textwithpicto($langs->trans("ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE"), $langs->trans("ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE_DESC", $langs->transnoentities("MenuDefaultAccounts"))).''; + print img_picto($langs->trans("Activated"), 'switch_on'); + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print '
'; + print '
'; print ''; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 620e4158ceb..01bfa1da942 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -416,7 +416,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($searchCategoryProductOperator == 1) { $param .= "&search_category_product_operator=".urlencode($searchCategoryProductOperator); diff --git a/htdocs/accountancy/admin/subaccount.php b/htdocs/accountancy/admin/subaccount.php index 40055a4b75f..31b99be39a3 100644 --- a/htdocs/accountancy/admin/subaccount.php +++ b/htdocs/accountancy/admin/subaccount.php @@ -296,7 +296,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_subaccount) { $param .= '&search_subaccount='.urlencode($search_subaccount); diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index fd8cd8ad688..c45a1202419 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -327,7 +327,7 @@ if ($action != 'export_csv') { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/accountancy/bookkeeping/export.php b/htdocs/accountancy/bookkeeping/export.php new file mode 100644 index 00000000000..91efdf29aec --- /dev/null +++ b/htdocs/accountancy/bookkeeping/export.php @@ -0,0 +1,1406 @@ + + * Copyright (C) 2013-2016 Florian Henry + * Copyright (C) 2013-2023 Alexandre Spangaro + * Copyright (C) 2022 Lionel Vessiller + * Copyright (C) 2016-2017 Laurent Destailleur + * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2022 Progiseize + * + * 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 htdocs/accountancy/bookkeeping/export.php + * \ingroup Accountancy (Double entries) + * \brief Export operation of book keeping + */ + +// Load Dolibarr environment +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("accountancy", "compta")); + +$socid = GETPOST('socid', 'int'); + +$action = GETPOST('action', 'aZ09'); +$massaction = GETPOST('massaction', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bookkeepinglist'; +$search_mvt_num = GETPOST('search_mvt_num', 'int'); +$search_doc_type = GETPOST("search_doc_type", 'alpha'); +$search_doc_ref = GETPOST("search_doc_ref", 'alpha'); +$search_date_startyear = GETPOST('search_date_startyear', 'int'); +$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); +$search_date_startday = GETPOST('search_date_startday', 'int'); +$search_date_endyear = GETPOST('search_date_endyear', 'int'); +$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); +$search_date_endday = GETPOST('search_date_endday', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); +$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); +$search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); +$search_date_creation_startyear = GETPOST('search_date_creation_startyear', 'int'); +$search_date_creation_startmonth = GETPOST('search_date_creation_startmonth', 'int'); +$search_date_creation_startday = GETPOST('search_date_creation_startday', 'int'); +$search_date_creation_endyear = GETPOST('search_date_creation_endyear', 'int'); +$search_date_creation_endmonth = GETPOST('search_date_creation_endmonth', 'int'); +$search_date_creation_endday = GETPOST('search_date_creation_endday', 'int'); +$search_date_creation_start = dol_mktime(0, 0, 0, $search_date_creation_startmonth, $search_date_creation_startday, $search_date_creation_startyear); +$search_date_creation_end = dol_mktime(23, 59, 59, $search_date_creation_endmonth, $search_date_creation_endday, $search_date_creation_endyear); +$search_date_modification_startyear = GETPOST('search_date_modification_startyear', 'int'); +$search_date_modification_startmonth = GETPOST('search_date_modification_startmonth', 'int'); +$search_date_modification_startday = GETPOST('search_date_modification_startday', 'int'); +$search_date_modification_endyear = GETPOST('search_date_modification_endyear', 'int'); +$search_date_modification_endmonth = GETPOST('search_date_modification_endmonth', 'int'); +$search_date_modification_endday = GETPOST('search_date_modification_endday', 'int'); +$search_date_modification_start = dol_mktime(0, 0, 0, $search_date_modification_startmonth, $search_date_modification_startday, $search_date_modification_startyear); +$search_date_modification_end = dol_mktime(23, 59, 59, $search_date_modification_endmonth, $search_date_modification_endday, $search_date_modification_endyear); +$search_date_export_startyear = GETPOST('search_date_export_startyear', 'int'); +$search_date_export_startmonth = GETPOST('search_date_export_startmonth', 'int'); +$search_date_export_startday = GETPOST('search_date_export_startday', 'int'); +$search_date_export_endyear = GETPOST('search_date_export_endyear', 'int'); +$search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int'); +$search_date_export_endday = GETPOST('search_date_export_endday', 'int'); +$search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear); +$search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); +$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int'); +$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int'); +$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int'); +$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int'); +$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int'); +$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); +$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); +$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); +$search_import_key = GETPOST("search_import_key", 'alpha'); + +//var_dump($search_date_start);exit; +if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { + $action = 'delbookkeepingyear'; +} +if (GETPOST("button_export_file_x") || GETPOST("button_export_file.x") || GETPOST("button_export_file")) { + $action = 'export_file'; +} + +$search_account_category = GETPOST('search_account_category', 'int'); + +$search_accountancy_code = GETPOST("search_accountancy_code", 'alpha'); +$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); +if ($search_accountancy_code_start == - 1) { + $search_accountancy_code_start = ''; +} +$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha'); +if ($search_accountancy_code_end == - 1) { + $search_accountancy_code_end = ''; +} + +$search_accountancy_aux_code = GETPOST("search_accountancy_aux_code", 'alpha'); +$search_accountancy_aux_code_start = GETPOST('search_accountancy_aux_code_start', 'alpha'); +if ($search_accountancy_aux_code_start == - 1) { + $search_accountancy_aux_code_start = ''; +} +$search_accountancy_aux_code_end = GETPOST('search_accountancy_aux_code_end', 'alpha'); +if ($search_accountancy_aux_code_end == - 1) { + $search_accountancy_aux_code_end = ''; +} +$search_mvt_label = GETPOST('search_mvt_label', 'alpha'); +$search_direction = GETPOST('search_direction', 'alpha'); +$search_debit = GETPOST('search_debit', 'alpha'); +$search_credit = GETPOST('search_credit', 'alpha'); +$search_ledger_code = GETPOST('search_ledger_code', 'array'); +$search_lettering_code = GETPOST('search_lettering_code', 'alpha'); +$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha'); + +// Load variable for pagination +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$optioncss = GETPOST('optioncss', 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page < 0) { + $page = 0; +} +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if ($sortorder == "") { + $sortorder = "ASC"; +} +if ($sortfield == "") { + $sortfield = "t.piece_num,t.rowid"; +} + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$object = new BookKeeping($db); +$hookmanager->initHooks(array('bookkeepingexport')); + +$formaccounting = new FormAccounting($db); +$form = new Form($db); + +if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->hasRight('accounting', 'mouvements', 'export')) { + if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('restore_lastsearch_values') && !GETPOST('search_accountancy_code_start')) { + $query = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; + $query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1"; + $res = $db->query($query); + + if ($res->num_rows > 0) { + $fiscalYear = $db->fetch_object($res); + $search_date_start = strtotime($fiscalYear->date_start); + $search_date_end = strtotime($fiscalYear->date_end); + } else { + $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); + $year_start = dol_print_date(dol_now(), '%Y'); + if (dol_print_date(dol_now(), '%m') < $month_start) { + $year_start--; // If current month is lower that starting fiscal month, we start last year + } + $year_end = $year_start + 1; + $month_end = $month_start - 1; + if ($month_end < 1) { + $month_end = 12; + $year_end--; + } + $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start); + $search_date_end = dol_get_last_day($year_end, $month_end); + } + } +} + + +$arrayfields = array( + 't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1), + 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1), + 't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1), + 't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1), + 't.numero_compte'=>array('label'=>$langs->trans("AccountAccountingShort"), 'checked'=>1), + 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1), + 't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1), + 't.debit'=>array('label'=>$langs->trans("AccountingDebit"), 'checked'=>1), + 't.credit'=>array('label'=>$langs->trans("AccountingCredit"), 'checked'=>1), + 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), + 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), + 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), + 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1, 'enabled'=>!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")), + 't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100), +); + +if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { + unset($arrayfields['t.lettering_code']); +} + +$accountancyexport = new AccountancyExport($db); +$listofformat = $accountancyexport->getType(); +$formatexportset = getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'); +if (empty($listofformat[$formatexportset])) { + $formatexportset = 1; +} + +$error = 0; + +if (!isModEnabled('accounting')) { + accessforbidden(); +} +if ($user->socid > 0) { + accessforbidden(); +} +if (!$user->hasRight('accounting', 'mouvements', 'lire')) { + accessforbidden(); +} + + +/* + * Actions + */ + +$param = ''; + +if (GETPOST('cancel', 'alpha')) { + $action = 'list'; $massaction = ''; +} +if (!GETPOST('confirmmassaction', 'alpha')) { + $massaction = ''; +} + +$parameters = array('socid'=>$socid); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + 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_mvt_num = ''; + $search_doc_type = ''; + $search_doc_ref = ''; + $search_doc_date = ''; + $search_account_category = ''; + $search_accountancy_code = ''; + $search_accountancy_code_start = ''; + $search_accountancy_code_end = ''; + $search_accountancy_aux_code = ''; + $search_accountancy_aux_code_start = ''; + $search_accountancy_aux_code_end = ''; + $search_mvt_label = ''; + $search_direction = ''; + $search_ledger_code = array(); + $search_date_startyear = ''; + $search_date_startmonth = ''; + $search_date_startday = ''; + $search_date_endyear = ''; + $search_date_endmonth = ''; + $search_date_endday = ''; + $search_date_start = ''; + $search_date_end = ''; + $search_date_creation_startyear = ''; + $search_date_creation_startmonth = ''; + $search_date_creation_startday = ''; + $search_date_creation_endyear = ''; + $search_date_creation_endmonth = ''; + $search_date_creation_endday = ''; + $search_date_creation_start = ''; + $search_date_creation_end = ''; + $search_date_modification_startyear = ''; + $search_date_modification_startmonth = ''; + $search_date_modification_startday = ''; + $search_date_modification_endyear = ''; + $search_date_modification_endmonth = ''; + $search_date_modification_endday = ''; + $search_date_modification_start = ''; + $search_date_modification_end = ''; + $search_date_export_startyear = ''; + $search_date_export_startmonth = ''; + $search_date_export_startday = ''; + $search_date_export_endyear = ''; + $search_date_export_endmonth = ''; + $search_date_export_endday = ''; + $search_date_export_start = ''; + $search_date_export_end = ''; + $search_date_validation_startyear = ''; + $search_date_validation_startmonth = ''; + $search_date_validation_startday = ''; + $search_date_validation_endyear = ''; + $search_date_validation_endmonth = ''; + $search_date_validation_endday = ''; + $search_date_validation_start = ''; + $search_date_validation_end = ''; + $search_debit = ''; + $search_credit = ''; + $search_lettering_code = ''; + $search_not_reconciled = ''; + $search_import_key = ''; + $toselect = array(); + } + + // Must be after the remove filter action, before the export. + $filter = array(); + if (!empty($search_date_start)) { + $filter['t.doc_date>='] = $search_date_start; + $tmp = dol_getdate($search_date_start); + $param .= '&search_date_startmonth='.urlencode($tmp['mon']).'&search_date_startday='.urlencode($tmp['mday']).'&search_date_startyear='.urlencode($tmp['year']); + } + if (!empty($search_date_end)) { + $filter['t.doc_date<='] = $search_date_end; + $tmp = dol_getdate($search_date_end); + $param .= '&search_date_endmonth='.urlencode($tmp['mon']).'&search_date_endday='.urlencode($tmp['mday']).'&search_date_endyear='.urlencode($tmp['year']); + } + if (!empty($search_doc_date)) { + $filter['t.doc_date'] = $search_doc_date; + $tmp = dol_getdate($search_doc_date); + $param .= '&doc_datemonth='.urlencode($tmp['mon']).'&doc_dateday='.urlencode($tmp['mday']).'&doc_dateyear='.urlencode($tmp['year']); + } + if (!empty($search_doc_type)) { + $filter['t.doc_type'] = $search_doc_type; + $param .= '&search_doc_type='.urlencode($search_doc_type); + } + if (!empty($search_doc_ref)) { + $filter['t.doc_ref'] = $search_doc_ref; + $param .= '&search_doc_ref='.urlencode($search_doc_ref); + } + if ($search_account_category != '-1' && !empty($search_account_category)) { + require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php'; + $accountingcategory = new AccountancyCategory($db); + + $listofaccountsforgroup = $accountingcategory->getCptsCat(0, 'fk_accounting_category = '.((int) $search_account_category)); + $listofaccountsforgroup2 = array(); + if (is_array($listofaccountsforgroup)) { + foreach ($listofaccountsforgroup as $tmpval) { + $listofaccountsforgroup2[] = "'".$db->escape($tmpval['id'])."'"; + } + } + $filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2); + $param .= '&search_account_category='.urlencode($search_account_category); + } + if (!empty($search_accountancy_code)) { + $filter['t.numero_compte'] = $search_accountancy_code; + $param .= '&search_accountancy_code='.urlencode($search_accountancy_code); + } + if (!empty($search_accountancy_code_start)) { + $filter['t.numero_compte>='] = $search_accountancy_code_start; + $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start); + } + if (!empty($search_accountancy_code_end)) { + $filter['t.numero_compte<='] = $search_accountancy_code_end; + $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); + } + if (!empty($search_accountancy_aux_code)) { + $filter['t.subledger_account'] = $search_accountancy_aux_code; + $param .= '&search_accountancy_aux_code='.urlencode($search_accountancy_aux_code); + } + if (!empty($search_accountancy_aux_code_start)) { + $filter['t.subledger_account>='] = $search_accountancy_aux_code_start; + $param .= '&search_accountancy_aux_code_start='.urlencode($search_accountancy_aux_code_start); + } + if (!empty($search_accountancy_aux_code_end)) { + $filter['t.subledger_account<='] = $search_accountancy_aux_code_end; + $param .= '&search_accountancy_aux_code_end='.urlencode($search_accountancy_aux_code_end); + } + if (!empty($search_mvt_label)) { + $filter['t.label_operation'] = $search_mvt_label; + $param .= '&search_mvt_label='.urlencode($search_mvt_label); + } + if (!empty($search_direction)) { + $filter['t.sens'] = $search_direction; + $param .= '&search_direction='.urlencode($search_direction); + } + if (!empty($search_ledger_code)) { + $filter['t.code_journal'] = $search_ledger_code; + foreach ($search_ledger_code as $code) { + $param .= '&search_ledger_code[]='.urlencode($code); + } + } + if (!empty($search_mvt_num)) { + $filter['t.piece_num'] = $search_mvt_num; + $param .= '&search_mvt_num='.urlencode($search_mvt_num); + } + if (!empty($search_date_creation_start)) { + $filter['t.date_creation>='] = $search_date_creation_start; + $tmp = dol_getdate($search_date_creation_start); + $param .= '&search_date_creation_startmonth='.urlencode($tmp['mon']).'&search_date_creation_startday='.urlencode($tmp['mday']).'&search_date_creation_startyear='.urlencode($tmp['year']); + } + if (!empty($search_date_creation_end)) { + $filter['t.date_creation<='] = $search_date_creation_end; + $tmp = dol_getdate($search_date_creation_end); + $param .= '&search_date_creation_endmonth='.urlencode($tmp['mon']).'&search_date_creation_endday='.urlencode($tmp['mday']).'&search_date_creation_endyear='.urlencode($tmp['year']); + } + if (!empty($search_date_modification_start)) { + $filter['t.tms>='] = $search_date_modification_start; + $tmp = dol_getdate($search_date_modification_start); + $param .= '&search_date_modification_startmonth='.urlencode($tmp['mon']).'&search_date_modification_startday='.urlencode($tmp['mday']).'&search_date_modification_startyear='.urlencode($tmp['year']); + } + if (!empty($search_date_modification_end)) { + $filter['t.tms<='] = $search_date_modification_end; + $tmp = dol_getdate($search_date_modification_end); + $param .= '&search_date_modification_endmonth='.urlencode($tmp['mon']).'&search_date_modification_endday='.urlencode($tmp['mday']).'&search_date_modification_endyear='.urlencode($tmp['year']); + } + if (!empty($search_date_export_start)) { + $filter['t.date_export>='] = $search_date_export_start; + $tmp = dol_getdate($search_date_export_start); + $param .= '&search_date_export_startmonth='.urlencode($tmp['mon']).'&search_date_export_startday='.urlencode($tmp['mday']).'&search_date_export_startyear='.urlencode($tmp['year']); + } + if (!empty($search_date_export_end)) { + $filter['t.date_export<='] = $search_date_export_end; + $tmp = dol_getdate($search_date_export_end); + $param .= '&search_date_export_endmonth='.urlencode($tmp['mon']).'&search_date_export_endday='.urlencode($tmp['mday']).'&search_date_export_endyear='.urlencode($tmp['year']); + } + if (!empty($search_date_validation_start)) { + $filter['t.date_validated>='] = $search_date_validation_start; + $tmp = dol_getdate($search_date_validation_start); + $param .= '&search_date_validation_startmonth='.urlencode($tmp['mon']).'&search_date_validation_startday='.urlencode($tmp['mday']).'&search_date_validation_startyear='.urlencode($tmp['year']); + } + if (!empty($search_date_validation_end)) { + $filter['t.date_validated<='] = $search_date_validation_end; + $tmp = dol_getdate($search_date_validation_end); + $param .= '&search_date_validation_endmonth='.urlencode($tmp['mon']).'&search_date_validation_endday='.urlencode($tmp['mday']).'&search_date_validation_endyear='.urlencode($tmp['year']); + } + if (!empty($search_debit)) { + $filter['t.debit'] = $search_debit; + $param .= '&search_debit='.urlencode($search_debit); + } + if (!empty($search_credit)) { + $filter['t.credit'] = $search_credit; + $param .= '&search_credit='.urlencode($search_credit); + } + if (!empty($search_lettering_code)) { + $filter['t.lettering_code'] = $search_lettering_code; + $param .= '&search_lettering_code='.urlencode($search_lettering_code); + } + if (!empty($search_not_reconciled)) { + $filter['t.reconciled_option'] = $search_not_reconciled; + $param .= '&search_not_reconciled='.urlencode($search_not_reconciled); + } + if (!empty($search_import_key)) { + $filter['t.import_key'] = $search_import_key; + $param .= '&search_import_key='.urlencode($search_import_key); + } + + if ($action == 'setreexport') { + $setreexport = GETPOST('value', 'int'); + if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) { + $error++; + } + + if (!$error) { + if ($conf->global->ACCOUNTING_REEXPORT == 1) { + setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'warnings'); + } + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } + } + + // Mass actions + $objectclass = 'Bookkeeping'; + $objectlabel = 'Bookkeeping'; + $permissiontoread = $user->hasRight('societe', 'lire'); + $permissiontodelete = $user->hasRight('societe', 'supprimer'); + $permissiontoadd = $user->hasRight('societe', 'creer'); + $uploaddir = $conf->societe->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + +// Build and execute select (used by page and export action) +// must de set after the action that set $filter +// -------------------------------------------------------------------- + +$sql = 'SELECT'; +$sql .= ' t.rowid,'; +$sql .= " t.doc_date,"; +$sql .= " t.doc_type,"; +$sql .= " t.doc_ref,"; +$sql .= " t.fk_doc,"; +$sql .= " t.fk_docdet,"; +$sql .= " t.thirdparty_code,"; +$sql .= " t.subledger_account,"; +$sql .= " t.subledger_label,"; +$sql .= " t.numero_compte,"; +$sql .= " t.label_compte,"; +$sql .= " t.label_operation,"; +$sql .= " t.debit,"; +$sql .= " t.credit,"; +$sql .= " t.lettering_code,"; +$sql .= " t.montant as amount,"; +$sql .= " t.sens,"; +$sql .= " t.fk_user_author,"; +$sql .= " t.import_key,"; +$sql .= " t.code_journal,"; +$sql .= " t.journal_label,"; +$sql .= " t.piece_num,"; +$sql .= " t.date_creation,"; +$sql .= " t.tms as date_modification,"; +$sql .= " t.date_export,"; +$sql .= " t.date_validated as date_validation,"; +$sql .= " t.import_key"; + +$sqlfields = $sql; // $sql fields to remove for count total + +$sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t'; +// Manage filter +$sqlwhere = array(); +if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.doc_date') { + $sqlwhere[] = $key."='".$db->idate($value)."'"; + } elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') { + $sqlwhere[] = $key."'".$db->idate($value)."'"; + } elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') { + $sqlwhere[] = $key."'".$db->escape($value)."'"; + } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { + $sqlwhere[] = $key.'='.((int) $value); + } elseif ($key == 't.subledger_account' || $key == 't.numero_compte') { + $sqlwhere[] = $key." LIKE '".$db->escape($value)."%'"; + } elseif ($key == 't.subledger_account') { + $sqlwhere[] = natural_search($key, $value, 0, 1); + } elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') { + $sqlwhere[] = $key."'".$db->idate($value)."'"; + } elseif ($key == 't.tms>=' || $key == 't.tms<=') { + $sqlwhere[] = $key."'".$db->idate($value)."'"; + } elseif ($key == 't.date_export>=' || $key == 't.date_export<=') { + $sqlwhere[] = $key."'".$db->idate($value)."'"; + } elseif ($key == 't.date_validated>=' || $key == 't.date_validated<=') { + $sqlwhere[] = $key."'".$db->idate($value)."'"; + } elseif ($key == 't.credit' || $key == 't.debit') { + $sqlwhere[] = natural_search($key, $value, 1, 1); + } elseif ($key == 't.reconciled_option') { + $sqlwhere[] = 't.lettering_code IS NULL'; + } elseif ($key == 't.code_journal' && !empty($value)) { + if (is_array($value)) { + $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1); + } else { + $sqlwhere[] = natural_search("t.code_journal", $value, 3, 1); + } + } elseif ($key == 't.search_accounting_code_in' && !empty($value)) { + $sqlwhere[] = 't.numero_compte IN ('.$db->sanitize($value, 1).')'; + } else { + $sqlwhere[] = natural_search($key, $value, 0, 1); + } + } +} +$sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')'; +if (!empty($conf->global->ACCOUNTING_REEXPORT)) { + $sql .= " AND t.date_export IS NULL"; +} +if (count($sqlwhere) > 0) { + $sql .= ' AND '.implode(' AND ', $sqlwhere); +} +//print $sql; + + +// Export into a file with format defined into setup (FEC, CSV, ...) +// Must be after definition of $sql +if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements', 'export')) { + // TODO Replace the fetchAll to get all ->line followed by call to ->export(). It currently consumes too much memory on large export. + // Replace this with the query($sql) and loop on each line to export them. + $result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1)); + + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { + // Export files then exit + $accountancyexport = new AccountancyExport($db); + + $formatexport = GETPOST('formatexport', 'int'); + $notexportlettering = GETPOST('notexportlettering', 'alpha'); + + if (!empty($notexportlettering)) { + if (is_array($object->lines)) { + foreach ($object->lines as $k => $movement) { + unset($object->lines[$k]->lettering_code); + unset($object->lines[$k]->date_lettering); + } + } + } + + $notifiedexportdate = GETPOST('notifiedexportdate', 'alpha'); + $notifiedvalidationdate = GETPOST('notifiedvalidationdate', 'alpha'); + $withAttachment = !empty(trim(GETPOST('notifiedexportfull', 'alphanohtml'))) ? 1 : 0; + + // Output data on screen or download + $result = $accountancyexport->export($object->lines, $formatexport, $withAttachment); + + $error = 0; + if ($result < 0) { + $error++; + } else { + if (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) { + if (is_array($object->lines)) { + dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); + + // Specify as export : update field date_export or date_validated + $db->begin(); + + // TODO Merge update for each line into one global using rowid IN (list of movement ids) + foreach ($object->lines as $movement) { + $now = dol_now(); + + $setfields = ''; + if (!empty($notifiedexportdate) && empty($movement->date_export)) { + $setfields .= ($setfields ? "," : "")." date_export = '".$db->idate($now)."'"; + } + if (!empty($notifiedvalidationdate) && empty($movement->date_validation)) { + $setfields .= ($setfields ? "," : "")." date_validated = '".$db->idate($now)."'"; + } + + if ($setfields) { + $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; + $sql .= " SET ".$setfields; + $sql .= " WHERE rowid = ".((int) $movement->id); + + $result = $db->query($sql); + if (!$result) { + $error++; + break; + } + } + } + + if (!$error) { + $db->commit(); + } else { + $error++; + $accountancyexport->errors[] = $langs->trans('NotAllExportedMovementsCouldBeRecordedAsExportedOrValidated'); + $db->rollback(); + } + } + } + } + + if ($error) { + setEventMessages('', $accountancyexport->errors, 'errors'); + header('Location: '.$_SERVER['PHP_SELF']); + } + exit(); // download or show errors + } +} + + +/* + * View + */ + +$formother = new FormOther($db); +$formfile = new FormFile($db); + +$title_page = $langs->trans("Operations").' - '.$langs->trans("ExportAccountancy"); + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); +} + +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} + +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title_page); + +$formconfirm = ''; + +if ($action == 'export_file') { + $form_question = array(); + + $form_question['formatexport'] = array( + 'name' => 'formatexport', + 'type' => 'select', + 'label' => $langs->trans('Modelcsv'), // TODO Use Selectmodelcsv and show a select combo + 'values' => $listofformat, + 'default' => $formatexportset, + 'morecss' => 'minwidth200 maxwidth200' + ); + + $form_question['separator0'] = array('name'=>'separator0', 'type'=>'separator'); + + if (getDolGlobalInt("ACCOUNTING_ENABLE_LETTERING")) { + // If 1, we check by default. + $checked = !empty($conf->global->ACCOUNTING_DEFAULT_NOT_EXPORT_LETTERING) ? 'true' : 'false'; + $form_question['notexportlettering'] = array( + 'name' => 'notexportlettering', + 'type' => 'checkbox', + 'label' => $langs->trans('NotExportLettering'), + 'value' => $checked, + ); + + $form_question['separator1'] = array('name'=>'separator1', 'type'=>'separator'); + } + + // If 1 or not set, we check by default. + $checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE)); + $form_question['notifiedexportdate'] = array( + 'name' => 'notifiedexportdate', + 'type' => 'checkbox', + 'label' => $langs->trans('NotifiedExportDate'), + 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), + ); + + $form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator'); + + if (!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")) { + // If 0 or not set, we NOT check by default. + $checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE)); + $form_question['notifiedvalidationdate'] = array( + 'name' => 'notifiedvalidationdate', + 'type' => 'checkbox', + 'label' => $langs->trans('NotifiedValidationDate', $langs->transnoentitiesnoconv("MenuAccountancyClosure")), + 'value' => $checked, + ); + + $form_question['separator3'] = array('name'=>'separator3', 'type'=>'separator'); + } + + // add documents in an archive for accountancy export (Quadratus) + if (getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_QUADRATUS) { + $form_question['notifiedexportfull'] = array( + 'name' => 'notifiedexportfull', + 'type' => 'checkbox', + 'label' => $langs->trans('NotifiedExportFull'), + 'value' => 'false', + ); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").'...', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 420, 600); +} + +// Print form confirm +print $formconfirm; + +//$param=''; param started before +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} + +// List of mass actions available +$arrayofmassactions = array(); +$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions); + +print '
'; +print ''; +print ''; +if ($optioncss != '') { + print ''; +} +print ''; +print ''; +print ''; +print ''; + +if (count($filter)) { + $buttonLabel = $langs->trans("ExportFilteredList"); +} else { + $buttonLabel = $langs->trans("ExportList"); +} + +$parameters = array('param' => $param); +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +$newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint; + +if (empty($reshook)) { + // Button re-export + if (!empty($conf->global->ACCOUNTING_REEXPORT)) { + $newcardbutton .= ''.img_picto($langs->trans("ClickToShowAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"'); + $newcardbutton .= ''.$langs->trans("ClickToShowAlreadyExportedLines").''; + $newcardbutton .= ''; + } else { + $newcardbutton .= ''.img_picto($langs->trans("DocsAlreadyExportedAreIncluded"), 'switch_on', 'class="warning size15x valignmiddle"'); + $newcardbutton .= ''.$langs->trans("DocsAlreadyExportedAreIncluded").''; + $newcardbutton .= ''; + } + + if ($user->hasRight('accounting', 'mouvements', 'export')) { + $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder), $user->hasRight('accounting', 'mouvements', 'export')); + } +} + +print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); + +// Not display message when all the list of docs are included +if (empty($conf->global->ACCOUNTING_REEXPORT)) { + print info_admin($langs->trans("WarningDataDisappearsWhenDataIsExported"), 0, 0, 0); +} +print '
'; + +//$topicmail = "Information"; +//$modelmail = "accountingbookkeeping"; +//$objecttmp = new BookKeeping($db); +//$trackid = 'bk'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +if ($massactionbutton && $contextpage != 'poslist') { + $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); +} + +$moreforfilter = ''; +$moreforfilter .= '
'; +$moreforfilter .= $langs->trans('AccountingCategory').': '; +$moreforfilter .= '
'; +$moreforfilter .= $formaccounting->select_accounting_category($search_account_category, 'search_account_category', 1, 0, 0, 0); +$moreforfilter .= '
'; +$moreforfilter .= '
'; + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + $moreforfilter .= $hookmanager->resPrint; +} else { + $moreforfilter = $hookmanager->resPrint; +} + +print '
'; +print $moreforfilter; +print '
'; + +print '
'; +print ''; + +// Filters lines +print ''; +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} +// Movement number +if (!empty($arrayfields['t.piece_num']['checked'])) { + print ''; +} +// Code journal +if (!empty($arrayfields['t.code_journal']['checked'])) { + print ''; +} +// Date document +if (!empty($arrayfields['t.doc_date']['checked'])) { + print ''; +} +// Ref document +if (!empty($arrayfields['t.doc_ref']['checked'])) { + print ''; +} +// Accountancy account +if (!empty($arrayfields['t.numero_compte']['checked'])) { + print ''; +} +// Subledger account +if (!empty($arrayfields['t.subledger_account']['checked'])) { + print ''; +} +// Label operation +if (!empty($arrayfields['t.label_operation']['checked'])) { + print ''; +} +// Debit +if (!empty($arrayfields['t.debit']['checked'])) { + print ''; +} +// Credit +if (!empty($arrayfields['t.credit']['checked'])) { + print ''; +} +// Lettering code +if (!empty($arrayfields['t.lettering_code']['checked'])) { + print ''; +} + +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +// Date creation +if (!empty($arrayfields['t.date_creation']['checked'])) { + print ''; +} +// Date modification +if (!empty($arrayfields['t.tms']['checked'])) { + print ''; +} +// Date export +if (!empty($arrayfields['t.date_export']['checked'])) { + print ''; +} +// Date validation +if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''; +} +if (!empty($arrayfields['t.import_key']['checked'])) { + print ''; +} +// Action column +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} +print "\n"; + +print ''; +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn ');} +if (!empty($arrayfields['t.piece_num']['checked'])) { + print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, "", $sortfield, $sortorder); +} +if (!empty($arrayfields['t.code_journal']['checked'])) { + print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.doc_date']['checked'])) { + print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.doc_ref']['checked'])) { + print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); +} +if (!empty($arrayfields['t.numero_compte']['checked'])) { + print_liste_field_titre($arrayfields['t.numero_compte']['label'], $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); +} +if (!empty($arrayfields['t.subledger_account']['checked'])) { + print_liste_field_titre($arrayfields['t.subledger_account']['label'], $_SERVER['PHP_SELF'], "t.subledger_account", "", $param, "", $sortfield, $sortorder); +} +if (!empty($arrayfields['t.label_operation']['checked'])) { + print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); +} +if (!empty($arrayfields['t.debit']['checked'])) { + print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); +} +if (!empty($arrayfields['t.credit']['checked'])) { + print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right '); +} +if (!empty($arrayfields['t.lettering_code']['checked'])) { + print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center '); +} +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (!empty($arrayfields['t.date_creation']['checked'])) { + print_liste_field_titre($arrayfields['t.date_creation']['label'], $_SERVER['PHP_SELF'], "t.date_creation", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.tms']['checked'])) { + print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER['PHP_SELF'], "t.tms", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.date_export']['checked'])) { + print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export,t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.date_validated']['checked'])) { + print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated,t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!empty($arrayfields['t.import_key']['checked'])) { + print_liste_field_titre($arrayfields['t.import_key']['label'], $_SERVER["PHP_SELF"], "t.import_key", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +} +print "\n"; + + +$line = new BookKeepingLine(); + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$totalarray = array(); +$totalarray['nbfield'] = 0; +$total_debit = 0; +$total_credit = 0; +$totalarray['val'] = array (); +$totalarray['val']['totaldebit'] = 0; +$totalarray['val']['totalcredit'] = 0; + +while ($i < min($num, $limit)) { + $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen + } + + $line->id = $obj->rowid; + $line->doc_date = $db->jdate($obj->doc_date); + $line->doc_type = $obj->doc_type; + $line->doc_ref = $obj->doc_ref; + $line->fk_doc = $obj->fk_doc; + $line->fk_docdet = $obj->fk_docdet; + $line->thirdparty_code = $obj->thirdparty_code; + $line->subledger_account = $obj->subledger_account; + $line->subledger_label = $obj->subledger_label; + $line->numero_compte = $obj->numero_compte; + $line->label_compte = $obj->label_compte; + $line->label_operation = $obj->label_operation; + $line->debit = $obj->debit; + $line->credit = $obj->credit; + $line->montant = $obj->amount; // deprecated + $line->amount = $obj->amount; + $line->sens = $obj->sens; + $line->lettering_code = $obj->lettering_code; + $line->fk_user_author = $obj->fk_user_author; + $line->import_key = $obj->import_key; + $line->code_journal = $obj->code_journal; + $line->journal_label = $obj->journal_label; + $line->piece_num = $obj->piece_num; + $line->date_creation = $db->jdate($obj->date_creation); + $line->date_modification = $db->jdate($obj->date_modification); + $line->date_export = $db->jdate($obj->date_export); + $line->date_validation = $db->jdate($obj->date_validation); + + $total_debit += $line->debit; + $total_credit += $line->credit; + + print ''; + // Action column + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Piece number + if (!empty($arrayfields['t.piece_num']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Journal code + if (!empty($arrayfields['t.code_journal']['checked'])) { + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('', $line->code_journal); + $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Document date + if (!empty($arrayfields['t.doc_date']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Document ref + if (!empty($arrayfields['t.doc_ref']['checked'])) { + if ($line->doc_type == 'customer_invoice') { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $objectstatic = new Facture($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'facture'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } elseif ($line->doc_type == 'supplier_invoice') { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $objectstatic = new FactureFournisseur($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'invoice_supplier'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir); + } elseif ($line->doc_type == 'expense_report') { + $langs->loadLangs(array('trips')); + + require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $objectstatic = new ExpenseReport($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'expensereport'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } elseif ($line->doc_type == 'bank') { + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $objectstatic = new AccountLine($db); + $objectstatic->fetch($line->fk_doc); + } else { + // Other type + } + + $labeltoshow = ''; + $labeltoshowalt = ''; + if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { + $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + $labeltoshow .= $documentlink; + $labeltoshowalt .= $objectstatic->ref; + } elseif ($line->doc_type == 'bank') { + $labeltoshow .= $objectstatic->getNomUrl(1); + $labeltoshowalt .= $objectstatic->ref; + $bank_ref = strstr($line->doc_ref, '-'); + $labeltoshow .= " " . $bank_ref; + $labeltoshowalt .= " " . $bank_ref; + } else { + $labeltoshow .= $line->doc_ref; + $labeltoshowalt .= $line->doc_ref; + } + + print '\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Account number + if (!empty($arrayfields['t.numero_compte']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Subledger account + if (!empty($arrayfields['t.subledger_account']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Label operation + if (!empty($arrayfields['t.label_operation']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Amount debit + if (!empty($arrayfields['t.debit']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'totaldebit'; + } + $totalarray['val']['totaldebit'] += $line->debit; + } + + // Amount credit + if (!empty($arrayfields['t.credit']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'totalcredit'; + } + $totalarray['val']['totalcredit'] += $line->credit; + } + + // Lettering code + if (!empty($arrayfields['t.lettering_code']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + // Creation operation date + if (!empty($arrayfields['t.date_creation']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Modification operation date + if (!empty($arrayfields['t.tms']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Exported operation date + if (!empty($arrayfields['t.date_export']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Validated operation date + if (!empty($arrayfields['t.date_validated']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + if (!empty($arrayfields['t.import_key']['checked'])) { + print '\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Action column + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + + print "\n"; + + $i++; +} + +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; +} + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print "
'; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; + print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth75'); + print ''; + print '
'; + print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print '
'; + print '
'; + print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth150', 'account'); + print '
'; + print '
'; + print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth150', 'account'); + print '
'; + print '
'; + // TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not + // use setup of keypress to select thirdparty and this hang browser on large database. + if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { + print '
'; + //print $langs->trans('From').' '; + print $formaccounting->select_auxaccount($search_accountancy_aux_code_start, 'search_accountancy_aux_code_start', $langs->trans('From'), 'maxwidth250', 'subledgeraccount'); + print '
'; + print '
'; + print $formaccounting->select_auxaccount($search_accountancy_aux_code_end, 'search_accountancy_aux_code_end', $langs->trans('to'), 'maxwidth250', 'subledgeraccount'); + print '
'; + } else { + print ''; + } + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'.$langs->trans("NotReconciled").''; + print '
'; + print '
'; + print $form->selectDate($search_date_creation_start, 'search_date_creation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_creation_end, 'search_date_creation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print '
'; + print '
'; + print $form->selectDate($search_date_modification_start, 'search_date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print '
'; + print $form->selectDate($search_date_export_start, 'search_date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_export_end, 'search_date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print '
'; + print '
'; + print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); + print '
'; + print '
'; + print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); + print '
'; + print '
'; + print ''; + print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'; + if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($line->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print ''; + $object->id = $line->id; + $object->piece_num = $line->piece_num; + print $object->getNomUrl(1, '', 0, '', 1); + print ''.$journaltoshow.''.dol_print_date($line->doc_date, 'day').''; + print $labeltoshow; + print "'.length_accountg($line->numero_compte).''.length_accounta($line->subledger_account).''.dol_escape_htmltag($line->label_operation).''.($line->debit != 0 ? price($line->debit) : '').''.($line->credit != 0 ? price($line->credit) : '').''.$line->lettering_code.''.dol_print_date($line->date_creation, 'dayhour', 'tzuserrel').''.dol_print_date($line->date_modification, 'dayhour', 'tzuserrel').''.dol_print_date($line->date_export, 'dayhour', 'tzuserrel').''.dol_print_date($line->date_validation, 'dayhour', 'tzuserrel').''.$obj->import_key."'; + if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($line->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'.$langs->trans("NoRecordFound").'
"; +print '
'; + +print '
'; + +// End of page +llxFooter(); + +$db->close(); diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 217474db0c9..d84c9212659 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2016 Florian Henry - * Copyright (C) 2013-2022 Alexandre Spangaro + * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2022 Lionel Vessiller * Copyright (C) 2016-2017 Laurent Destailleur * Copyright (C) 2018-2021 Frédéric France @@ -29,7 +29,6 @@ // Load Dolibarr environment require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; @@ -96,14 +95,6 @@ $search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_star $search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); $search_import_key = GETPOST("search_import_key", 'alpha'); -//var_dump($search_date_start);exit; -if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { - $action = 'delbookkeepingyear'; -} -if (GETPOST("button_export_file_x") || GETPOST("button_export_file.x") || GETPOST("button_export_file")) { - $action = 'export_file'; -} - $search_account_category = GETPOST('search_account_category', 'int'); $search_accountancy_code = GETPOST("search_accountancy_code", 'alpha'); @@ -159,7 +150,7 @@ $hookmanager->initHooks(array('bookkeepinglist')); $formaccounting = new FormAccounting($db); $form = new Form($db); -if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->hasRight('accounting', 'mouvements', 'export')) { +if (!in_array($action, array('delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->hasRight('accounting', 'mouvements', 'export')) { if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('restore_lastsearch_values') && !GETPOST('search_accountancy_code_start')) { $query = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; $query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1"; @@ -201,8 +192,8 @@ $arrayfields = array( 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), - 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), - 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1, 'enabled'=>!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")), + 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>0), + 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>0, 'enabled'=>!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")), 't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100), ); @@ -210,13 +201,6 @@ if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { unset($arrayfields['t.lettering_code']); } -$accountancyexport = new AccountancyExport($db); -$listofformat = $accountancyexport->getType(); -$formatexportset = getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'); -if (empty($listofformat[$formatexportset])) { - $formatexportset = 1; -} - $error = 0; if (!isModEnabled('accounting')) { @@ -457,49 +441,6 @@ if (empty($reshook)) { $param .= '&search_import_key='.urlencode($search_import_key); } - //if ($action == 'delbookkeepingyearconfirm' && !$user->hasRight('accounting', 'mouvements', 'supprimer_tous')) { - // $delmonth = GETPOST('delmonth', 'int'); - // $delyear = GETPOST('delyear', 'int'); - // if ($delyear == -1) { - // $delyear = 0; - // } - // $deljournal = GETPOST('deljournal', 'alpha'); - // if ($deljournal == -1) { - // $deljournal = 0; - // } - // - // if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { - // $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); - // if ($result < 0) { - // setEventMessages($object->error, $object->errors, 'errors'); - // } else { - // setEventMessages("RecordDeleted", null, 'mesgs'); - // } - // - // // Make a redirect to avoid to launch the delete later after a back button - // header("Location: list.php".($param ? '?'.$param : '')); - // exit; - // } else { - // setEventMessages("NoRecordDeleted", null, 'warnings'); - // } - //} - if ($action == 'setreexport') { - $setreexport = GETPOST('value', 'int'); - if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) { - $error++; - } - - if (!$error) { - if ($conf->global->ACCOUNTING_REEXPORT == 1) { - setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'warnings'); - } - } else { - setEventMessages($langs->trans("Error"), null, 'errors'); - } - } - // Mass actions $objectclass = 'Bookkeeping'; $objectlabel = 'Bookkeeping'; @@ -707,103 +648,12 @@ if (count($filter) > 0) { } } $sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')'; -if (empty($conf->global->ACCOUNTING_REEXPORT)) { - $sql .= " AND t.date_export IS NULL"; -} + if (count($sqlwhere) > 0) { $sql .= ' AND '.implode(' AND ', $sqlwhere); } //print $sql; - -// Export into a file with format defined into setup (FEC, CSV, ...) -// Must be after definition of $sql -if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements', 'export')) { - // TODO Replace the fetchAll to get all ->line followed by call to ->export(). It currently consumes too much memory on large export. - // Replace this with the query($sql) and loop on each line to export them. - $result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1)); - - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - // Export files then exit - $accountancyexport = new AccountancyExport($db); - - $formatexport = GETPOST('formatexport', 'int'); - $notexportlettering = GETPOST('notexportlettering', 'alpha'); - - if (!empty($notexportlettering)) { - if (is_array($object->lines)) { - foreach ($object->lines as $k => $movement) { - unset($object->lines[$k]->lettering_code); - unset($object->lines[$k]->date_lettering); - } - } - } - - $notifiedexportdate = GETPOST('notifiedexportdate', 'alpha'); - $notifiedvalidationdate = GETPOST('notifiedvalidationdate', 'alpha'); - $withAttachment = !empty(trim(GETPOST('notifiedexportfull', 'alphanohtml'))) ? 1 : 0; - - // Output data on screen or download - $result = $accountancyexport->export($object->lines, $formatexport, $withAttachment); - - $error = 0; - if ($result < 0) { - $error++; - } else { - if (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) { - if (is_array($object->lines)) { - dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); - - // Specify as export : update field date_export or date_validated - $db->begin(); - - // TODO Merge update for each line into one gloacl using rowid IN (list of movement ids) - foreach ($object->lines as $movement) { - $now = dol_now(); - - $setfields = ''; - if (!empty($notifiedexportdate) && empty($movement->date_export)) { - $setfields .= ($setfields ? "," : "")." date_export = '".$db->idate($now)."'"; - } - if (!empty($notifiedvalidationdate) && empty($movement->date_validation)) { - $setfields .= ($setfields ? "," : "")." date_validated = '".$db->idate($now)."'"; - } - - if ($setfields) { - $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; - $sql .= " SET ".$setfields; - $sql .= " WHERE rowid = ".((int) $movement->id); - - $result = $db->query($sql); - if (!$result) { - $error++; - break; - } - } - } - - if (!$error) { - $db->commit(); - } else { - $error++; - $accountancyexport->errors[] = $langs->trans('NotAllExportedMovementsCouldBeRecordedAsExportedOrValidated'); - $db->rollback(); - } - } - } - } - - if ($error) { - setEventMessages('', $accountancyexport->errors, 'errors'); - header('Location: '.$_SERVER['PHP_SELF']); - } - exit(); // download or show errors - } -} - - /* * View */ @@ -857,111 +707,6 @@ llxHeader('', $title_page); $formconfirm = ''; -if ($action == 'export_file') { - $form_question = array(); - - $form_question['formatexport'] = array( - 'name' => 'formatexport', - 'type' => 'select', - 'label' => $langs->trans('Modelcsv'), // TODO Use Selectmodelcsv and show a select combo - 'values' => $listofformat, - 'default' => $formatexportset, - 'morecss' => 'minwidth200 maxwidth200' - ); - - $form_question['separator0'] = array('name'=>'separator0', 'type'=>'separator'); - - if (getDolGlobalInt("ACCOUNTING_ENABLE_LETTERING")) { - // If 1, we check by default. - $checked = !empty($conf->global->ACCOUNTING_DEFAULT_NOT_EXPORT_LETTERING) ? 'true' : 'false'; - $form_question['notexportlettering'] = array( - 'name' => 'notexportlettering', - 'type' => 'checkbox', - 'label' => $langs->trans('NotExportLettering'), - 'value' => $checked, - ); - - $form_question['separator1'] = array('name'=>'separator1', 'type'=>'separator'); - } - - // If 1 or not set, we check by default. - $checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE)); - $form_question['notifiedexportdate'] = array( - 'name' => 'notifiedexportdate', - 'type' => 'checkbox', - 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), - ); - - $form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator'); - - if (!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")) { - // If 0 or not set, we NOT check by default. - $checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE)); - $form_question['notifiedvalidationdate'] = array( - 'name' => 'notifiedvalidationdate', - 'type' => 'checkbox', - 'label' => $langs->trans('NotifiedValidationDate', $langs->transnoentitiesnoconv("MenuAccountancyClosure")), - 'value' => $checked, - ); - - $form_question['separator3'] = array('name'=>'separator3', 'type'=>'separator'); - } - - // add documents in an archive for accountancy export (Quadratus) - if (getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_QUADRATUS) { - $form_question['notifiedexportfull'] = array( - 'name' => 'notifiedexportfull', - 'type' => 'checkbox', - 'label' => $langs->trans('NotifiedExportFull'), - 'value' => 'false', - ); - } - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").'...', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 420, 600); -} - -//if ($action == 'delbookkeepingyear') { -// $form_question = array(); -// $delyear = GETPOST('delyear', 'int'); -// $deljournal = GETPOST('deljournal', 'alpha'); -// -// if (empty($delyear)) { -// $delyear = dol_print_date(dol_now(), '%Y'); -// } -// $month_array = array(); -// for ($i = 1; $i <= 12; $i++) { -// $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); -// } -// $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); -// $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); -// -// $form_question['delmonth'] = array( -// 'name' => 'delmonth', -// 'type' => 'select', -// 'label' => $langs->trans('DelMonth'), -// 'values' => $month_array, -// 'morecss' => 'minwidth150', -// 'default' => '' -// ); -// $form_question['delyear'] = array( -// 'name' => 'delyear', -// 'type' => 'select', -// 'label' => $langs->trans('DelYear'), -// 'values' => $year_array, -// 'default' => $delyear -// ); -// $form_question['deljournal'] = array( -// 'name' => 'deljournal', -// 'type' => 'other', // We don't use select here, the journal_array is already a select html component -// 'label' => $langs->trans('DelJournal'), -// 'value' => $journal_array, -// 'default' => $deljournal -// ); -// -// $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 320); -//} - // Print form confirm print $formconfirm; @@ -970,7 +715,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } // List of mass actions available @@ -1015,21 +760,6 @@ if ($reshook < 0) { $newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint; if (empty($reshook)) { - // Button re-export - if (!empty($conf->global->ACCOUNTING_REEXPORT)) { - $newcardbutton .= ''.img_picto($langs->trans("ClickToHideAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"'); - $newcardbutton .= ''.$langs->trans("ClickToHideAlreadyExportedLines").''; - $newcardbutton .= ''; - } else { - $newcardbutton .= ''.img_picto($langs->trans("DocsAlreadyExportedAreExcluded"), 'switch_on', 'class="warning size15x valignmiddle"'); - $newcardbutton .= ''.$langs->trans("DocsAlreadyExportedAreExcluded").''; - $newcardbutton .= ''; - } - - if ($user->hasRight('accounting', 'mouvements', 'export')) { - $newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder), $user->hasRight('accounting', 'mouvements', 'export')); - } - $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?type=sub'.$param, '', 1, array('morecss' => 'marginleftonly')); @@ -1608,13 +1338,6 @@ print $hookmanager->resPrint; print ""; print ''; -// TODO Replace this with mass delete action -//if ($user->rights->accounting->mouvements->supprimer_tous) { -// print '
'."\n"; -// print ''.$langs->trans("DeleteMvt").''; -// print '
'; -//} - print ''; // End of page diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 419369fe9d3..599e2360147 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -686,7 +686,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 8c21b070d9f..a3c39cb06ee 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -816,8 +816,8 @@ class AccountancyExport // Keep correct quadra named field instead of anon filler libelle_ecriture2 is 30 char not 32 !!!! // as we use utf8, we must remove accent to have only one ascii char instead of utf8 2 chars for specials that report wrong line size that will exceed import format spec // TODO: we should filter more than only accent to avoid wrong line size - // TODO: remove invoice number doc_ref in libelle, - // TODO: we should offer an option for customer to build the libelle using invoice number / name / date in accounting software + // TODO: remove invoice number doc_ref in label, + // TODO: we should offer an option for customer to build the label using invoice number / name / date in accounting software //$Tab['libelle_ecriture2'] = str_pad(self::trunc($data->doc_ref . ' ' . $data->label_operation, 30), 30); $Tab['libelle_ecriture2'] = str_pad(self::trunc($data->label_operation, 30), 30); $Tab['codetva'] = str_repeat(' ', 2); diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 8e5f7690dd1..0fd2fb2e61d 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -684,10 +684,10 @@ class AccountingAccount extends CommonObject } /** - * Retourne le libelle du statut d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -696,11 +696,11 @@ class AccountingAccount extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status * - * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function LibStatut($status, $mode = 0) { diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 7c71d073629..f59ba4559e1 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -312,10 +312,10 @@ class AccountingJournal extends CommonObject } /** - * Retourne le libelle du statut d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court - * @return string Label of type + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibType($mode = 0) { @@ -327,7 +327,7 @@ class AccountingJournal extends CommonObject * Return type of an accounting journal * * @param int $nature Id type - * @param int $mode 0=libelle long, 1=libelle court + * @param int $mode 0=label long, 1=label short * @return string Label of type */ public function LibType($nature, $mode = 0) diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 888cc568cf8..0e5ecd25563 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -65,10 +65,10 @@ $search_country = GETPOST('search_country', 'alpha'); $search_tvaintra = GETPOST('search_tvaintra', 'alpha'); // Load variable for pagination -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusonPour le détail de la facture ref…e') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0) { $page = 0; } @@ -81,6 +81,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_DONE > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -159,6 +161,12 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->hasRight('ac } } +if (GETPOST('sortfield') == 'f.datef, f.ref, fd.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_DONE", $value, 'yesno', 0, '', $conf->entity); +} + /* * View @@ -317,7 +325,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_societe) { $param .= "&search_societe=".urlencode($search_societe); diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 8834ad69cf8..509e131f766 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -91,6 +91,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -208,6 +210,11 @@ if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { } } +if (GETPOST('sortfield') == 'f.datef, f.ref, l.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $value, 'yesno', 0, '', $conf->entity); +} /* @@ -382,7 +389,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_societe) { $param .= '&search_societe='.urlencode($search_societe); diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index 1d0653fc5ac..fbb92ebb18e 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -75,6 +75,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_DONE > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -149,6 +151,12 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco } } +if (GETPOST('sortfield') == 'erd.date, erd.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_DONE", $value, 'yesno', 0, '', $conf->entity); +} + /* * View @@ -248,7 +256,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_login) { $param .= '&search_login='.urlencode($search_login); diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 4ad8c80a2c1..e8822f2f669 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -84,6 +84,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -199,6 +201,11 @@ if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { } } +if (GETPOST('sortfield') == 'erd.date, erd.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $value, 'yesno', 0, '', $conf->entity); +} /* @@ -306,7 +313,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_login) { $param .= '&search_login='.urlencode($search_login); diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 0137e63406f..89f495a97bc 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -1211,6 +1211,8 @@ if (empty($action) || $action == 'view') { print ''.($mt >= 0 ? price($mt) : '').""; print ''.($mt < 0 ? price(-$mt) : '').""; print ""; + + $i++; } } @@ -1336,6 +1338,8 @@ if (empty($action) || $action == 'view') { print ''.($mt >= 0 ? price($mt) : '').""; print ""; + + $i++; } } } else { // Waiting account @@ -1373,11 +1377,18 @@ if (empty($action) || $action == 'view') { print ''.($mt < 0 ? price(-$mt) : '').""; print ''.($mt >= 0 ? price($mt) : '').""; print ""; + + $i++; } } } } + if (!$i) { + $colspan = 8; + print ''.$langs->trans("NoRecordFound").''; + } + print ""; print ''; diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index ffffc21a9f9..514edeb4528 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -615,6 +615,8 @@ if (empty($action) || $action == 'view') { print ''.($mt >= 0 ? price($mt) : '').""; print ''.($mt < 0 ? price(-$mt) : '').""; print ""; + + $i++; } } @@ -649,6 +651,8 @@ if (empty($action) || $action == 'view') { print ''.($mt < 0 ? price(-$mt) : '').""; print ''.($mt >= 0 ? price($mt) : '').""; print ""; + + $i++; } // VAT @@ -685,11 +689,18 @@ if (empty($action) || $action == 'view') { print ''.($mt >= 0 ? price($mt) : '').""; print ''.($mt < 0 ? price(-$mt) : '').""; print ""; + + $i++; } } } } + if (!$i) { + $colspan = 7; + print ''.$langs->trans("NoRecordFound").''; + } + print ""; print ''; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 12303089dca..319328cdc6e 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -3,7 +3,7 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2023 Alexandre Spangaro * Copyright (C) 2013-2016 Olivier Geffroy * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2018 Frédéric France @@ -32,6 +32,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; @@ -103,9 +104,11 @@ if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)) $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle,f.ref_supplier, f.date_lim_reglement as dlr, f.close_code,"; +$sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle as label, f.ref_supplier, f.date_lim_reglement as dlr, f.close_code, f.vat_reverse_charge,"; $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.vat_src_code, fd.info_bits,"; -$sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur,"; +$sql .= " p.default_vat_code AS product_buy_default_vat_code, p.tva_tx as product_buy_vat, p.localtax1_tx as product_buy_localvat1, p.localtax2_tx as product_buy_localvat2,"; +$sql .= " co.code as country_code, co.label as country_label,"; +$sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.fk_pays,"; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { $sql .= " spe.accountancy_code_customer as code_compta,"; $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,"; @@ -127,6 +130,7 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; $sql .= " JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = fd.fk_facture_fourn"; $sql .= " JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); } @@ -166,12 +170,18 @@ if ($result) { $tablocaltax2 = array(); $tabcompany = array(); $tabother = array(); + $tabrctva = array(); + $tabrclocaltax1 = array(); + $tabrclocaltax2 = array(); $num = $db->num_rows($result); // Variables $cptfour = ($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER != "") ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : 'NotDefined'; $cpttva = (!empty($conf->global->ACCOUNTING_VAT_BUY_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_BUY_ACCOUNT : 'NotDefined'; + $rcctva = (!empty($conf->global->ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT)) ? $conf->global->ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT : 'NotDefined'; + $rcdtva = (!empty($conf->global->ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT)) ? $conf->global->ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT : 'NotDefined'; + $country_code_in_EEC = getCountriesInEEC(); // This make a database call but there is a cache done into $conf->cache['country_code_in_EEC'] $i = 0; while ($i < $num) { @@ -230,6 +240,53 @@ if ($result) { $tablocaltax2[$obj->rowid][$compta_localtax2] = 0; } + // VAT Reverse charge + if (($mysoc->country_code == 'FR' || !empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) && $obj->vat_reverse_charge == 1 && in_array($obj->country_code, $country_code_in_EEC)) { + $rcvatdata = getTaxesFromId($obj->product_buy_vat . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : ''), $mysoc, $mysoc, 0); + $rcc_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva); + $rcd_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva); + $rcc_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva); + $rcd_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva); + $rcc_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva); + $rcd_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva); + if (price2num($obj->product_buy_vat) || !empty($obj->product_buy_default_vat_code)) { + $vat_key = vatrate($obj->product_buy_vat) . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : ''); + $val_value = $vat_key; + $def_tva[$obj->rowid][$rcc_compta_tva][$vat_key] = $val_value; + $def_tva[$obj->rowid][$rcd_compta_tva][$vat_key] = $val_value; + } + + if (!isset($tabrctva[$obj->rowid][$rcc_compta_tva])) { + $tabrctva[$obj->rowid][$rcc_compta_tva] = 0; + } + if (!isset($tabrctva[$obj->rowid][$rcd_compta_tva])) { + $tabrctva[$obj->rowid][$rcd_compta_tva] = 0; + } + if (!isset($tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1])) { + $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] = 0; + } + if (!isset($tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1])) { + $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] = 0; + } + if (!isset($tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2])) { + $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] = 0; + } + if (!isset($tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2])) { + $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] = 0; + } + + $rcvat = (double) price2num($obj->total_ttc * $obj->product_buy_vat / 100, 'MT'); + $rclocalvat1 = (double) price2num($obj->total_ttc * $obj->product_buy_localvat1 / 100, 'MT'); + $rclocalvat2 = (double) price2num($obj->total_ttc * $obj->product_buy_localvat2 / 100, 'MT'); + + $tabrctva[$obj->rowid][$rcd_compta_tva] += $rcvat; + $tabrctva[$obj->rowid][$rcc_compta_tva] -= $rcvat; + $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] += $rclocalvat1; + $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] -= $rclocalvat1; + $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] += $rclocalvat2; + $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] -= $rclocalvat2; + } + $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc; $tabht[$obj->rowid][$compta_prod] += $obj->total_ht; $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva; @@ -470,6 +527,29 @@ if ($action == 'writebookkeeping') { $arrayofvat = $tablocaltax2; } + // VAT Reverse charge + if ($mysoc->country_code == 'FR' || !empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) { + $has_vat = false; + foreach ($arrayofvat[$key] as $k => $mt) { + if ($mt) { + $has_vat = true; + } + } + + if (!$has_vat) { + $arrayofvat = $tabrctva; + if ($numtax == 1) { + $arrayofvat = $tabrclocaltax1; + } + if ($numtax == 2) { + $arrayofvat = $tabrclocaltax2; + } + if (!is_array($arrayofvat[$key])) { + $arrayofvat[$key] = array(); + } + } + } + foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label @@ -720,6 +800,29 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! $arrayofvat = $tablocaltax2; } + // VAT Reverse charge + if ($mysoc->country_code == 'FR' || !empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) { + $has_vat = false; + foreach ($arrayofvat[$key] as $k => $mt) { + if ($mt) { + $has_vat = true; + } + } + + if (!$has_vat) { + $arrayofvat = $tabrctva; + if ($numtax == 1) { + $arrayofvat = $tabrclocaltax1; + } + if ($numtax == 2) { + $arrayofvat = $tabrclocaltax2; + } + if (!is_array($arrayofvat[$key])) { + $arrayofvat[$key] = array(); + } + } + } + foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { print '"'.$key.'"'.$sep; @@ -998,6 +1101,29 @@ if (empty($action) || $action == 'view') { $arrayofvat = $tablocaltax2; } + // VAT Reverse charge + if ($mysoc->country_code == 'FR' || !empty($conf->global->ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE)) { + $has_vat = false; + foreach ($arrayofvat[$key] as $k => $mt) { + if ($mt) { + $has_vat = true; + } + } + + if (!$has_vat) { + $arrayofvat = $tabrctva; + if ($numtax == 1) { + $arrayofvat = $tabrclocaltax1; + } + if ($numtax == 2) { + $arrayofvat = $tabrclocaltax2; + } + if (!is_array($arrayofvat[$key])) { + $arrayofvat[$key] = array(); + } + } + } + foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { print ''; diff --git a/htdocs/accountancy/journal/variousjournal.php b/htdocs/accountancy/journal/variousjournal.php index cf652a29345..621683ea4cb 100644 --- a/htdocs/accountancy/journal/variousjournal.php +++ b/htdocs/accountancy/journal/variousjournal.php @@ -272,9 +272,10 @@ $object_label = $langs->trans("ObjectsRef"); if ($object->nature == 2 || $object->nature == 3) $object_label = $langs->trans("InvoiceRef"); if ($object->nature == 5) $object_label = $langs->trans("ExpenseReportRef"); -/* - * Show result array - */ + +// Show result array +$i = 0; + print '
'; print '
'; @@ -304,11 +305,21 @@ if (is_array($journal_data) && !empty($journal_data)) { print '' . $line['debit'] . ''; print '' . $line['credit'] . ''; print ''; + + $i++; } } } } +if (!$i) { + $colspan = 7; + if ($object->nature == 4) { + $colspan++; + } + print ''.$langs->trans("NoRecordFound").''; +} + print ''; print '
'; diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index ea9841d2fbb..11c4bf290fd 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -83,6 +83,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_DONE > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -164,6 +166,12 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco } } +if (GETPOST('sortfield') == 'f.datef, f.ref, l.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_DONE", $value, 'yesno', 0, '', $conf->entity); +} + /* * View @@ -322,7 +330,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_societe) { $param .= "&search_societe=".urlencode($search_societe); diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 3ec92f490bd..9c9ee109383 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -93,6 +93,8 @@ if (!$sortfield) { if (!$sortorder) { if ($conf->global->ACCOUNTING_LIST_SORT_VENTILATION_TODO > 0) { $sortorder = "DESC"; + } else { + $sortorder = "ASC"; } } @@ -210,6 +212,11 @@ if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { } } +if (GETPOST('sortfield') == 'f.datef, f.ref, l.rowid') { + $value = (GETPOST('sortorder') == 'asc,asc,asc' ? 0 : 1); + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $value, 'yesno', 0, '', $conf->entity); +} /* @@ -386,7 +393,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_societe) { $param .= '&search_societe='.urlencode($search_societe); diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index 6bf2a084563..867f4f47025 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -73,7 +73,7 @@ $search_agenda_label = GETPOST('search_agenda_label'); $objcanvas = null; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('memberagenda')); +$hookmanager->initHooks(array('memberagenda', 'globalcard')); // Security check $result = restrictedArea($user, 'adherent', $id); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 4bc3e3e55e4..5816c5c4ea1 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1403,7 +1403,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; print dol_get_fiche_end(); - print $form->buttonsSaveCancel("Save", ''); + print $form->buttonsSaveCancel("Save", 'Cancel'); print ''; } @@ -2041,7 +2041,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($useonlinepayment) { print '
'; if (empty($amount)) { // Take the maximum amount among what the member is supposed to pay / has paid in the past - $amount = price(max($adht->amount, $object->first_subscription_amount, $object->last_subscription_amount)); + $amount = max($adht->amount, $object->first_subscription_amount, $object->last_subscription_amount); } if (empty($amount)) { $amount = 0; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 7f9adb32266..a4a4c0c71bb 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1247,7 +1247,7 @@ class Adherent extends CommonObject if ($result >= 0) { $result = $luser->setPassword($user, $this->pass, 0, 0, 1); - if ($result < 0) { + if (is_numeric($result) && $result < 0) { $this->error = $luser->error; dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR); $error++; @@ -2413,8 +2413,7 @@ class Adherent extends CommonObject } // Only picto if ($withpictoimg > 0) { - $picto = ''. - img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams.' class="'.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1).''; + $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).''; } else { // Picto must be a photo $picto = ''; @@ -3062,7 +3061,7 @@ class Adherent extends CommonObject $blockingerrormsg = ''; - if (empty($conf->adherent->enabled)) { // Should not happen. If module disabled, cron job should not be visible. + if (!isModEnabled('adherent')) { // Should not happen. If module disabled, cron job should not be visible. $langs->load("agenda"); $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent")); return 0; diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 9ee0de6c055..ea7c68bbff8 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -774,7 +774,7 @@ class AdherentType extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (' class="'.(($withpicto != 2) ? 'paddingright' : '').'"'), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= ($maxlen ?dol_trunc($this->label, $maxlen) : $this->label); diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index 5f8dbf07249..90f211d7a33 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -452,10 +452,10 @@ class Subscription extends CommonObject /** - * Retourne le libelle du statut d'une adhesion + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -464,16 +464,19 @@ class Subscription extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status * - * @param int $status Id status - * @return string Label + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ - public function LibStatut($status) + public function LibStatut($status, $mode = 0) { // phpcs:enable global $langs; - $langs->load("members"); + + //$langs->load("members"); + return ''; } diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 35d4015e270..37261676e98 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -188,7 +188,8 @@ $result = restrictedArea($user, 'adherent'); */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -324,14 +325,17 @@ $formother = new FormOther($db); $membertypestatic = new AdherentType($db); $memberstatic = new Adherent($db); +$now = dol_now(); + // Page Header $title = $langs->trans("Members")." - ".$langs->trans("List"); $help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros|DE:Modul_Mitglieder'; -llxHeader('', $title, $help_url); +$morejs = array(); +$morecss = array(); -$now = dol_now(); - +// Build and execute select +// -------------------------------------------------------------------- if ((!empty($search_categ) && $search_categ > 0) || !empty($catid)) { $sql = "SELECT DISTINCT"; } else { @@ -356,7 +360,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { // Add fields from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql = preg_replace('/,\s*$/', '', $sql); @@ -487,16 +491,14 @@ if ($search_country) { if ($search_import_key) { $sql .= natural_search("d.import_key", $search_import_key); } - // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; - // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -// Count total nb of records with no order and no limits +// Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* The fast and low memory method to get and count full list converts the sql into a sql count */ @@ -510,7 +512,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } @@ -533,8 +535,7 @@ if (!$resql) { $num = $db->num_rows($resql); -$arrayofselected = is_array($toselect) ? $toselect : array(); - +// Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $sall) { $obj = $db->fetch_object($resql); $id = $obj->rowid; @@ -542,6 +543,13 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ exit; } +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist'); // Can use also classforhorizontalscrolloftabs instead of bodyforlist for no horizontal scroll + +$arrayofselected = is_array($toselect) ? $toselect : array(); + if ($search_type > 0) { $membertype = new AdherentType($db); @@ -558,7 +566,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($sall != "") { $param .= "&sall=".urlencode($sall); @@ -712,7 +720,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields if ($massactionbutton) { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } @@ -1351,7 +1359,7 @@ if ($num == 0) { $colspan++; } } - print ''.$langs->trans("NoRecordFound").''; + print ''.$langs->trans("NoRecordFound").''; } $db->free($resql); diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index ea2796ae910..8296fd5591d 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -451,7 +451,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } $param .= '&id='.$rowid; if ($optioncss != '') { diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 394a17433f4..622accdd5b1 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -50,6 +50,7 @@ $mode = GETPOST('mode', 'alopha'); $sall = GETPOST("sall", "alpha"); $filter = GETPOST("filter", 'alpha'); +$search_ref = GETPOST('search_ref', 'alpha'); $search_lastname = GETPOST('search_lastname', 'alpha'); $search_login = GETPOST('search_login', 'alpha'); $search_email = GETPOST('search_email', 'alpha'); @@ -96,15 +97,6 @@ $hookmanager->initHooks(array('membertypecard', 'globalcard')); // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); -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_lastname = ""; - $search_login = ""; - $search_email = ""; - $type = ""; - $sall = ""; -} - - // Security check $result = restrictedArea($user, 'adherent', $rowid, 'adherent_type'); @@ -113,6 +105,15 @@ $result = restrictedArea($user, 'adherent', $rowid, 'adherent_type'); * Actions */ +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_ref = ""; + $search_lastname = ""; + $search_login = ""; + $search_email = ""; + $type = ""; + $sall = ""; +} + if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; @@ -456,12 +457,12 @@ if ($action == 'create') { print ''.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('comment', (GETPOSTISSET('comment') ? GETPOST('comment', 'restricthtml') : $object->note_public), '', 200, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('comment', (GETPOSTISSET('comment') ? GETPOST('comment', 'restricthtml') : $object->note_public), '', 200, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor'), 15, '90%'); $doleditor->Create(); print ''.$langs->trans("WelcomeEMail").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('mail_valid', GETPOSTISSET('mail_valid') ? GETPOST('mail_valid') : $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('mail_valid', GETPOSTISSET('mail_valid') ? GETPOST('mail_valid') : $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor'), 15, '90%'); $doleditor->Create(); print ''; @@ -549,6 +550,7 @@ if ($rowid > 0) { print dol_get_fiche_end(); + /* * Buttons */ @@ -561,8 +563,16 @@ if ($rowid > 0) { } // Add + if ($object->morphy == 'phy') { + $morphy = 'phy'; + } elseif ($object->morphy == 'mor') { + $morphy = 'mor'; + } else { + $morphy = ''; + } + if ($user->hasRight('adherent', 'configurer')&& !empty($object->status)) { - print ''; + print ''; } else { print ''; } @@ -581,9 +591,9 @@ if ($rowid > 0) { $now = dol_now(); - $sql = "SELECT d.rowid, d.login, d.firstname, d.lastname, d.societe as company,"; + $sql = "SELECT d.rowid, d.ref, d.entity, d.login, d.firstname, d.lastname, d.societe as company, d.fk_soc,"; $sql .= " d.datefin,"; - $sql .= " d.email, d.fk_adherent_type as type_id, d.morphy, d.statut as status,"; + $sql .= " d.email, d.photo, d.fk_adherent_type as type_id, d.morphy, d.statut as status,"; $sql .= " t.libelle as type, t.subscription, t.amount"; $sqlfields = $sql; // $sql fields to remove for count total @@ -603,6 +613,9 @@ if ($rowid > 0) { $sql .= natural_search(array("d.firstname", "d.lastname"), GETPOST('search', 'alpha')); } } + if (!empty($search_ref)) { + $sql .= natural_search("d.ref", $search_ref); + } if (!empty($search_lastname)) { $sql .= natural_search(array("d.firstname", "d.lastname"), $search_lastname); } @@ -691,6 +704,9 @@ if ($rowid > 0) { if (!empty($status)) { $param .= "&status=".urlencode($status); } + if (!empty($search_ref)) { + $param .= "&search_ref=".urlencode($search_ref); + } if (!empty($search_lastname)) { $param .= "&search_lastname=".urlencode($search_lastname); } @@ -732,6 +748,9 @@ if ($rowid > 0) { print ''; } + print ''; + print ''; + print ''; print ''; @@ -761,6 +780,7 @@ if ($rowid > 0) { if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print_liste_field_titre("Action", $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder); } + print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.ref", $param, "", "", $sortfield, $sortorder); print_liste_field_titre("NameSlashCompany", $_SERVER["PHP_SELF"], "d.lastname", $param, "", "", $sortfield, $sortorder); print_liste_field_titre("Login", $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder); print_liste_field_titre("MemberNature", $_SERVER["PHP_SELF"], "d.morphy", $param, "", "", $sortfield, $sortorder); @@ -780,13 +800,19 @@ if ($rowid > 0) { $datefin = $db->jdate($objp->datefin); + $adh->id = $objp->rowid; + $adh->ref = $objp->ref; + $adh->login = $objp->login; $adh->lastname = $objp->lastname; $adh->firstname = $objp->firstname; $adh->datefin = $datefin; $adh->need_subscription = $objp->subscription; $adh->statut = $objp->status; + $adh->email = $objp->email; + $adh->photo = $objp->photo; print ''; + // Actions if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; @@ -798,6 +824,12 @@ if ($rowid > 0) { } print ""; } + + // Ref + print ""; + print $adh->getNomUrl(-1, 0, 'card', 'ref', '', -1, 0, 1); + print "\n"; + // Lastname if ($objp->company != '') { print ''.img_object($langs->trans("ShowMember"), "user", 'class="paddingright"').$adh->getFullName($langs, 0, -1, 20).' / '.dol_trunc($objp->company, 12).''."\n"; @@ -943,12 +975,12 @@ if ($rowid > 0) { print ''.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('comment', $object->note_public, '', 220, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('comment', $object->note_public, '', 220, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor'), 15, '90%'); $doleditor->Create(); print ""; print ''.$langs->trans("WelcomeEMail").''; - $doleditor = new DolEditor('mail_valid', $object->mail_valid, '', 280, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('mail_valid', $object->mail_valid, '', 280, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor'), 15, '90%'); $doleditor->Create(); print ""; diff --git a/htdocs/adherents/type_translation.php b/htdocs/adherents/type_translation.php index 85b346b4225..38988d4aa34 100644 --- a/htdocs/adherents/type_translation.php +++ b/htdocs/adherents/type_translation.php @@ -289,7 +289,7 @@ if ($action == 'create' && $user->hasRight('adherent', 'configurer')) { print ''; print ''.$langs->trans('Label').''; print ''.$langs->trans('Description').''; - $doleditor = new DolEditor('desc', '', '', 160, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, ROWS_3, '90%'); + $doleditor = new DolEditor('desc', '', '', 160, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor'), ROWS_3, '90%'); $doleditor->Create(); print ''; diff --git a/htdocs/admin/accounting.php b/htdocs/admin/accounting.php index fba458936b8..18d383a1b3c 100644 --- a/htdocs/admin/accounting.php +++ b/htdocs/admin/accounting.php @@ -55,6 +55,7 @@ $error = 0; $title = $langs->trans("ConfigAccountingExpert"); $help_url = ''; + llxHeader('', $title, $help_url); $linkback = ''.$langs->trans("BackToModuleList").''; diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 7c7eecc84f0..b6e30f65454 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -161,7 +161,7 @@ if (!empty($triggers)) { $module = 'fournisseur'; } if ($module == 'shipping') { - $module = 'expedition_bon'; + $module = 'expedition'; } if ($module == 'member') { $module = 'adherent'; diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index b366ea928ef..93db0398687 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -531,7 +531,7 @@ print ''; print ''; print $langs->trans("PaymentMode").''; print ''; -if (empty($conf->facture->enabled)) { +if (!isModEnabled('facture')) { print ''; } print ''; @@ -540,7 +540,7 @@ print "\n"; print ''; print "".$langs->trans("SuggestPaymentByRIBOnAccount").""; print ""; -if (empty($conf->facture->enabled)) { +if (!isModEnabled('facture')) { if (isModEnabled("banque")) { $sql = "SELECT rowid, label"; $sql .= " FROM ".MAIN_DB_PREFIX."bank_account"; @@ -579,7 +579,7 @@ print ""; print ''; print "".$langs->trans("SuggestPaymentByChequeToAddress").""; print ""; -if (empty($conf->facture->enabled)) { +if (!isModEnabled('facture')) { print ''; print ''; print ''; -print ''."\n"; +print ''."\n"; // Name print ''; print '
'.$langs->trans("CompanyInfo").''.$langs->trans("Value").'
'.$langs->trans("CompanyInfo").'
'; @@ -572,12 +572,14 @@ print '
'; + print '
'; + // IDs of the company (country-specific) print '
'; print ''; -print ''; +print ''; $langs->load("companies"); @@ -688,7 +690,7 @@ print ''; print '
'; print '
'.$langs->trans("CompanyIds").''.$langs->trans("Value").'
'.$langs->trans("CompanyIds").'
'; print ''; -print ''; +print ''; print "\n"; print ''; } elseif ($value == 'country_id') { if (!in_array('country', $fieldlist)) { // If there is already a field country, we don't show country_id (avoid duplicate) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 880589fb5b1..98a4eec28fb 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -603,7 +603,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Filters print '
'; - print '
'.$langs->trans("FiscalYearInformation").''.$langs->trans("Value").''.$langs->trans("FiscalYearInformation").'
'; @@ -703,7 +705,7 @@ print load_fiche_titre($langs->trans("TypeOfSaleTaxes"), '', 'object_payment'); print ''; print ''; -print ''; +print ''; print ''; print "\n"; @@ -733,7 +735,7 @@ print "
'.$langs->trans("VATManagement").''.$langs->trans("Description").''.$langs->trans("VATManagement").' 
"; print '
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; @@ -777,7 +779,7 @@ print "
'.$form->textwithpicto($langs->transcountry("LocalTax1Management", $mysoc->country_code), $langs->transcountry("LocalTax1IsUsedDesc", $mysoc->country_code)).''.$langs->trans("Description").''.$form->textwithpicto($langs->transcountry("LocalTax1Management", $mysoc->country_code), $langs->transcountry("LocalTax1IsUsedDesc", $mysoc->country_code)).' 
"; print '
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; @@ -821,7 +823,7 @@ print "
'.$form->textwithpicto($langs->transcountry("LocalTax2Management", $mysoc->country_code), $langs->transcountry("LocalTax2IsUsedDesc", $mysoc->country_code)).''.$langs->trans("Description").''.$form->textwithpicto($langs->transcountry("LocalTax2Management", $mysoc->country_code), $langs->transcountry("LocalTax2IsUsedDesc", $mysoc->country_code)).' 
"; print '
'; print ''; print ''; -print ''; +print ''; print ''; print "\n"; if ($mysoc->useRevenueStamp()) { diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index 4baddd8b29b..81f1da40615 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -226,7 +226,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); @@ -383,7 +383,12 @@ if (!is_array($result) && $result < 0) { print ''; } - print ''; + // Multicompany + print ''; // Actions print ''; @@ -1609,25 +1611,56 @@ if ($id > 0) { $i = 0; // There is several pages - if ($num > $listlimit || $page) { + if (($num > $listlimit) || $page) { print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); print '
'; } + $filterfound = 0; + foreach ($fieldlist as $field => $value) { + if ($value == 'entity') { + continue; + } + + $showfield = 1; // By default + if ($value == 'region_id' || $value == 'country_id') { + $showfield = 0; + } + + if ($showfield) { + if ($value == 'country') { + $filterfound++; + } elseif ($value == 'code') { + $filterfound++; + } + } + } + print '
'; print '
'.$form->textwithpicto($langs->trans("RevenueStamp"), $langs->trans("RevenueStampDesc")).''.$langs->trans("Description").''.$form->textwithpicto($langs->trans("RevenueStamp"), $langs->trans("RevenueStampDesc")).' 
'; + if (isModEnabled('multicompany')) { + print dol_escape_htmltag($defaultvalue->entity); + } + print ''; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 33833162b11..210413b87f2 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -101,7 +101,7 @@ $hookmanager->initHooks(array('admin', 'dictionaryadmin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0, 44, 0); +$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 31, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0, 44, 0); // Name of SQL tables of dictionaries $tabname = array(); @@ -135,7 +135,7 @@ $tabname[27] = "c_stcomm"; $tabname[28] = "c_holiday_types"; $tabname[29] = "c_lead_status"; $tabname[30] = "c_format_cards"; -//$tabname[31]= "accounting_system"; +$tabname[31] = "c_invoice_subtype"; $tabname[32] = "c_hrm_public_holiday"; $tabname[33] = "c_hrm_department"; $tabname[34] = "c_hrm_function"; @@ -182,7 +182,7 @@ $tablib[27] = "DictionaryProspectStatus"; $tablib[28] = "DictionaryHolidayTypes"; $tablib[29] = "DictionaryOpportunityStatus"; $tablib[30] = "DictionaryFormatCards"; -//$tablib[31]= "DictionaryAccountancysystem"; +$tablib[31] = "DictionaryInvoiceSubtype"; $tablib[32] = "DictionaryPublicHolidays"; $tablib[33] = "DictionaryDepartment"; $tablib[34] = "DictionaryFunction"; @@ -205,10 +205,10 @@ $tabsql[3] = "SELECT r.rowid as rowid, r.code_region as state_code, r.nom as lib $tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite, c.eec FROM ".MAIN_DB_PREFIX."c_country AS c"; $tabsql[5] = "SELECT c.rowid as rowid, c.code as code, c.label, c.active FROM ".MAIN_DB_PREFIX."c_civility AS c"; $tabsql[6] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.type, a.active, a.module, a.color, a.position FROM ".MAIN_DB_PREFIX."c_actioncomm AS a"; -$tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays=c.rowid and c.active=1"; +$tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays = c.rowid and c.active = 1"; $tabsql[8] = "SELECT t.id as rowid, t.code as code, t.libelle, t.fk_country as country_id, c.code as country_code, c.label as country, t.position, t.active FROM ".MAIN_DB_PREFIX."c_typent as t LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON t.fk_country=c.rowid"; $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAIN_DB_PREFIX."c_currencies AS c"; -$tabsql[10] = "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; +$tabsql[10] = "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays = c.rowid"; $tabsql[11] = "SELECT t.rowid as rowid, t.element, t.source, t.code, t.libelle, t.position, t.active FROM ".MAIN_DB_PREFIX."c_type_contact AS t"; $tabsql[12] = "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.deposit_percent, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = ".getEntity($tabname[12]); $tabsql[13] = "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = ".getEntity($tabname[13]); @@ -229,7 +229,7 @@ $tabsql[27] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN $tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.block_if_negative, h.sortorder, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; $tabsql[29] = "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30] = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; -//$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s"; +$tabsql[31] = "SELECT t.rowid, t.code, t.label, c.label as country, c.code as country_code, t.fk_country as country_id, t.active FROM ".MAIN_DB_PREFIX."c_invoice_subtype as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_country = c.rowid"; $tabsql[32] = "SELECT a.id as rowid, a.entity, a.code, a.fk_country as country_id, c.code as country_code, c.label as country, a.dayrule, a.day, a.month, a.year, a.active FROM ".MAIN_DB_PREFIX."c_hrm_public_holiday as a LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON a.fk_country=c.rowid AND c.active=1"; $tabsql[33] = "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department"; $tabsql[34] = "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function"; @@ -276,7 +276,7 @@ $tabsqlsort[27] = "code ASC"; $tabsqlsort[28] = "sortorder ASC, country ASC, code ASC"; $tabsqlsort[29] = "position ASC"; $tabsqlsort[30] = "code ASC"; -//$tabsqlsort[31]="pcg_version ASC"; +$tabsqlsort[31] = "country ASC, code ASC"; $tabsqlsort[32] = "country, year ASC, month ASC, day ASC"; $tabsqlsort[33] = "code ASC"; $tabsqlsort[34] = "code ASC"; @@ -323,7 +323,7 @@ $tabfield[27] = "code,libelle,picto"; $tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country,block_if_negative,sortorder"; $tabfield[29] = "code,label,percent,position"; $tabfield[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; -//$tabfield[31]= "pcg_version,label"; +$tabfield[31] = "country_id,country,code,label"; $tabfield[32] = "code,dayrule,year,month,day,country_id,country"; $tabfield[33] = "code,label"; $tabfield[34] = "code,label"; @@ -370,7 +370,7 @@ $tabfieldvalue[27] = "code,libelle,picto"; $tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country,block_if_negative,sortorder"; $tabfieldvalue[29] = "code,label,percent,position"; $tabfieldvalue[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; -//$tabfieldvalue[31]= "pcg_version,label"; +$tabfieldvalue[31] = "country,code,label"; $tabfieldvalue[32] = "code,dayrule,day,month,year,country"; $tabfieldvalue[33] = "code,label"; $tabfieldvalue[34] = "code,label"; @@ -417,8 +417,7 @@ $tabfieldinsert[27] = "code,libelle,picto"; $tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country,block_if_negative,sortorder"; $tabfieldinsert[29] = "code,label,percent,position"; $tabfieldinsert[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; -//$tabfieldinsert[31]= "pcg_version,label"; -//$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country"; +$tabfieldinsert[31] = "fk_country,code,label"; $tabfieldinsert[32] = "code,dayrule,day,month,year,fk_country"; $tabfieldinsert[33] = "code,label"; $tabfieldinsert[34] = "code,label"; @@ -467,7 +466,7 @@ $tabrowid[27] = "id"; $tabrowid[28] = ""; $tabrowid[29] = ""; $tabrowid[30] = ""; -//$tabrowid[31]= ""; +$tabrowid[31]= ""; $tabrowid[32] = "id"; $tabrowid[33] = "rowid"; $tabrowid[34] = "rowid"; @@ -495,15 +494,15 @@ $tabcond[8] = isModEnabled("societe"); $tabcond[9] = true; $tabcond[10] = true; $tabcond[11] = (isModEnabled("societe")); -$tabcond[12] = (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_invoice") || isModEnabled("supplier_order")); -$tabcond[13] = (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_invoice") || isModEnabled("supplier_order")); +$tabcond[12] = (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || isModEnabled("supplier_invoice") || isModEnabled("supplier_order")); +$tabcond[13] = (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || isModEnabled("supplier_invoice") || isModEnabled("supplier_order")); $tabcond[14] = (isModEnabled("product") && (isModEnabled('ecotax') || !empty($conf->global->MAIN_SHOW_ECOTAX_DICTIONNARY))); $tabcond[15] = true; $tabcond[16] = (isModEnabled("societe") && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)); $tabcond[17] = (isModEnabled('deplacement') || isModEnabled('expensereport')); $tabcond[18] = isModEnabled("expedition") || isModEnabled("reception"); $tabcond[19] = isModEnabled("societe"); -$tabcond[20] = (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order"); +$tabcond[20] = isModEnabled("supplier_order"); $tabcond[21] = isModEnabled("propal"); $tabcond[22] = (isModEnabled('commande') || isModEnabled("propal")); $tabcond[23] = true; @@ -514,7 +513,7 @@ $tabcond[27] = isModEnabled("societe"); $tabcond[28] = isModEnabled('holiday'); $tabcond[29] = isModEnabled('project'); $tabcond[30] = (isModEnabled('label') || isModEnabled('barcode') || isModEnabled('adherent')); // stickers format dictionary -//$tabcond[31]= isModEnabled('accounting'); +$tabcond[31] = ((isModEnabled('facture') || isModEnabled('supplier_invoice')) && $mysoc->country_code == 'GR'); $tabcond[32] = (isModEnabled('holiday') || isModEnabled('hrm')); $tabcond[33] = isModEnabled('hrm'); $tabcond[34] = isModEnabled('hrm'); @@ -576,6 +575,7 @@ $tabcomplete = array( 'c_product_nature'=>array('picto'=>'product', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), 'c_productbatch_qcstatus'=>array('picto'=>'lot', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), 'c_asset_disposal_type'=>array('picto'=>'asset', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_invoice_subtype'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), ); @@ -714,7 +714,7 @@ if (empty($reshook)) { $ok = 1; foreach ($listfield as $f => $value) { // Discard check of mandatory fields for country for some tables - if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { + if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryInvoiceSubtype', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { continue; // For some pages, country is not mandatory } if ($value == 'country' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryCanton', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp'))) { @@ -1201,7 +1201,7 @@ if ($search_country_id > 0) { $param .= '&search_country_id='.urlencode($search_country_id); } if ($search_code != '') { - $param .= '&search_code='.urlencode($search_country_id); + $param .= '&search_code='.urlencode($search_code); } if ($entity != '') { $param .= '&entity='.(int) $entity; @@ -1580,7 +1580,9 @@ if ($id > 0) { } print ''; if ($action != 'edit') { - print ''; + print ''; + } else { + print ''; } print '
'; // Title line with search input fields print ''."\n"; print ''; - $filterfound = 0; + + // Action button + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + $colspan++; + } + + $colspan = 0; foreach ($fieldlist as $field => $value) { if ($value == 'entity') { continue; } $showfield = 1; // By default - if ($value == 'region_id' || $value == 'country_id') { $showfield = 0; } @@ -1637,34 +1670,51 @@ if ($id > 0) { print ''; - $filterfound++; + $colspan++; } elseif ($value == 'code') { print ''; - $filterfound++; + $colspan++; } else { print ''; + $colspan++; } } } if ($id == 4) { print ''; + $colspan++; print ''; + $colspan++; } + print ''; - print ''; + $colspan++; } - print ''; + print ''; // Title of lines print ''."\n"; print ''; + + // Action button + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList(''); + } + foreach ($fieldlist as $field => $value) { if ($value == 'entity') { continue; @@ -1896,17 +1946,90 @@ if ($id > 0) { print getTitleFieldOfList($langs->trans("Favorite"), 0, $_SERVER["PHP_SELF"], "favorite", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); } + // Status print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); - print getTitleFieldOfList(''); - print getTitleFieldOfList(''); + + // Action button + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList(''); + } print ''; if ($num) { // Lines with values while ($i < $num) { $obj = $db->fetch_object($resql); + + // Can an entry be erased or disabled ? + // all true by default + $iserasable = 1; + $canbedisabled = 1; + $canbemodified = 1; + if (isset($obj->code) && $id != 10 && $id != 42) { + if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i', $obj->code))) { + $iserasable = 0; $canbedisabled = 0; + } elseif ($obj->code == 'RECEP') { + $iserasable = 0; $canbedisabled = 0; + } elseif ($obj->code == 'EF0') { + $iserasable = 0; $canbedisabled = 0; + } + } + if ($id == 25 && in_array($obj->code, array('banner', 'blogpost', 'other', 'page'))) { + $iserasable = 0; $canbedisabled = 0; + if (in_array($obj->code, array('banner'))) { + $canbedisabled = 1; + } + } + if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) { + $iserasable = 0; + } + if (in_array(empty($obj->code) ? '' : $obj->code, array('AC_OTH', 'AC_OTH_AUTO')) || in_array(empty($obj->type) ? '' : $obj->type, array('systemauto'))) { + $canbedisabled = 0; $canbedisabled = 0; + } + $canbemodified = $iserasable; + + if (!empty($obj->code) && $obj->code == 'RECEP') { + $canbemodified = 1; + } + if ($tabname[$id] == "c_actioncomm") { + $canbemodified = 1; + } + + // Build Url. The table is id=, the id of line is rowid= + $rowidcol = $tabrowid[$id]; + // If rowidcol not defined + if (empty($rowidcol) || in_array($id, array(6, 7, 8, 13, 17, 19, 27, 32))) { + $rowidcol = 'rowid'; + } + $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(isset($obj->{$rowidcol}) ? $obj->{$rowidcol} : (!empty($obj->code) ? urlencode($obj->code) : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); + if (!empty($param)) { + $url .= '&'.$param; + } + if (!is_null($withentity)) { + $url .= '&entity='.$withentity; + } + $url .= '&'; + + //print_r($obj); print ''; + + // Action button + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { $tmpaction = 'edit'; $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); @@ -2141,56 +2264,6 @@ if ($id > 0) { } } - // Can an entry be erased or disabled ? - // all true by default - $iserasable = 1; - $canbedisabled = 1; - $canbemodified = 1; - if (isset($obj->code) && $id != 10 && $id != 42) { - if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i', $obj->code))) { - $iserasable = 0; $canbedisabled = 0; - } elseif ($obj->code == 'RECEP') { - $iserasable = 0; $canbedisabled = 0; - } elseif ($obj->code == 'EF0') { - $iserasable = 0; $canbedisabled = 0; - } - } - if ($id == 25 && in_array($obj->code, array('banner', 'blogpost', 'other', 'page'))) { - $iserasable = 0; $canbedisabled = 0; - if (in_array($obj->code, array('banner'))) { - $canbedisabled = 1; - } - } - if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) { - $iserasable = 0; - } - if (in_array(empty($obj->code) ? '' : $obj->code, array('AC_OTH', 'AC_OTH_AUTO')) || in_array(empty($obj->type) ? '' : $obj->type, array('systemauto'))) { - $canbedisabled = 0; $canbedisabled = 0; - } - $canbemodified = $iserasable; - - if (!empty($obj->code) && $obj->code == 'RECEP') { - $canbemodified = 1; - } - if ($tabname[$id] == "c_actioncomm") { - $canbemodified = 1; - } - - // Build Url. The table is id=, the id of line is rowid= - $rowidcol = $tabrowid[$id]; - // If rowidcol not defined - if (empty($rowidcol) || in_array($id, array(6, 7, 8, 13, 17, 19, 27, 32))) { - $rowidcol = 'rowid'; - } - $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(isset($obj->{$rowidcol}) ? $obj->{$rowidcol} : (!empty($obj->code) ? urlencode($obj->code) : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); - if (!empty($param)) { - $url .= '&'.$param; - } - if (!is_null($withentity)) { - $url .= '&entity='.$withentity; - } - $url .= '&'; - // Favorite & EEC // Only activated on country dictionary if ($id == 4) { @@ -2229,29 +2302,28 @@ if ($id > 0) { } print ""; - // Modify link - if ($canbemodified) { - print ''; - } else { - print ''; - } - - // Delete link - if ($iserasable) { - print ''; - } else { - print ''; } print "\n"; } $i++; } + } else { + print ''; } print '
'; + if ($filterfound) { + $searchpicto = $form->showFilterAndCheckAddButtons(0); + print $searchpicto; + } + print ''; print $form->select_country($search_country_id, 'search_country_id', '', 28, 'minwidth100 maxwidth150 maxwidthonsmartphone'); print ''; print ''; print ''; print ''; - if ($filterfound) { - $searchpicto = $form->showFilterAndCheckAddButtons(0); - print $searchpicto; + $colspan++; + + // Action button + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if ($filterfound) { + $searchpicto = $form->showFilterAndCheckAddButtons(0); + print $searchpicto; + } + print '
'; + // Modify link + if ($canbemodified) { + print ''.img_edit().''; + } + // Delete link + if ($iserasable) { + if ($user->admin) { + print ''.img_delete().''; + } + } + print ''.img_edit().' '; - if ($user->admin) { - print ''.img_delete().''; + // Action button + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + // Modify link + if ($canbemodified) { + print ''.img_edit().''; + } + // Delete link + if ($iserasable) { + if ($user->admin) { + print ''.img_delete().''; + } } - //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin print ' 
'.$langs->trans("NoRecordFound").'
'; @@ -2372,8 +2444,12 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') continue; } // For state page, we do not show the country input (we link to region, not country) print '
'; - $fieldname = 'country'; - print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')), $fieldname, '', 28, 'minwidth100 maxwidth150 maxwidthonsmartphone'); + + $selected = (!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')); + if (!GETPOSTISSET('code')) { + $selected = GETPOST('countryidforinsert'); + } + print $form->select_country($selected, $value, '', 28, 'minwidth100 maxwidth150 maxwidthonsmartphone'); print '
'; + print '
'; print ''; print ''; print ''; @@ -615,20 +615,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea 'to'=>array('label'=>'MailTo', 'data-placeholder'=>$langs->trans('SearchString')), 'cc'=>array('label'=>'Cc', 'data-placeholder'=>$langs->trans('SearchString')), 'bcc'=>array('label'=>'Bcc', 'data-placeholder'=>$langs->trans('SearchString')), + 'replyto'=>array('label'=>'ReplyTo', 'data-placeholder'=>$langs->trans('SearchString')), 'subject'=>array('label'=>'Subject', 'data-placeholder'=>$langs->trans('SearchString')), 'body'=>array('label'=>'Body', 'data-placeholder'=>$langs->trans('SearchString')), // disabled because PHP imap_search is not compatible IMAPv4, only IMAPv2 //'header'=>array('label'=>'Header', 'data-placeholder'=>'HeaderKey SearchString'), // HEADER key value //'X1'=>'---', - //'notinsubject'=>array('label'=>'SubjectNotIn', 'data-placeholder'=>'SearchString'), - //'notinbody'=>array('label'=>'BodyNotIn', 'data-placeholder'=>'SearchString'), 'X2'=>'---', 'seen'=>array('label'=>'AlreadyRead', 'data-noparam'=>1), 'unseen'=>array('label'=>'NotRead', 'data-noparam'=>1), 'unanswered'=>array('label'=>'Unanswered', 'data-noparam'=>1), 'answered'=>array('label'=>'Answered', 'data-noparam'=>1), - 'smaller'=>array('label'=>'SmallerThan', 'data-placeholder'=>$langs->trans('NumberOfBytes')), - 'larger'=>array('label'=>'LargerThan', 'data-placeholder'=>$langs->trans('NumberOfBytes')), + 'smaller'=>array('label'=>$langs->trans("Size").' ('.$langs->trans("SmallerThan").")", 'data-placeholder'=>$langs->trans('NumberOfBytes')), + 'larger'=>array('label'=>$langs->trans("Size").' ('.$langs->trans("LargerThan").")", 'data-placeholder'=>$langs->trans('NumberOfBytes')), 'X3'=>'---', 'withtrackingid'=>array('label'=>'WithDolTrackingID', 'data-noparam'=>1), 'withouttrackingid'=>array('label'=>'WithoutDolTrackingID', 'data-noparam'=>1), @@ -662,7 +661,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; - print ''; + print ''; print ''; // List filters foreach ($object->filters as $rulefilter) { @@ -690,7 +689,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print '
'.img_picto('', 'filter', 'class="pictofixedwidth opacitymedium"').$form->textwithpicto($langs->trans("Filters"), $langs->trans("EmailCollectorFilterDesc")).'
'; print ''; print '
'; print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print ''; $arrayoftypes = array( @@ -730,13 +735,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; - print ''; + print ''; print ''; // List operations $nboflines = count($object->actions); @@ -766,12 +769,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; // Move up/down diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index ccee1f604b2..20d9ddf4ac9 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -337,7 +337,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php index 5a5c2f25c0e..ff7178a9ed3 100644 --- a/htdocs/admin/fckeditor.php +++ b/htdocs/admin/fckeditor.php @@ -64,7 +64,7 @@ $conditions = array( 'NOTE_PRIVATE' => 1, 'SOCIETE' => 1, 'PRODUCTDESC' => (isModEnabled("product") || isModEnabled("service")), - 'DETAILS' => (isModEnabled('facture') || isModEnabled("propal") || isModEnabled('commande') || isModEnabled('supplier_proposal') || (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")), + 'DETAILS' => (isModEnabled('facture') || isModEnabled("propal") || isModEnabled('commande') || isModEnabled('supplier_proposal') || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")), 'USERSIGN' => 1, 'MAILING' => isModEnabled('mailing'), 'MAIL' => (isModEnabled('facture') || isModEnabled("propal") || isModEnabled('commande')), diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 504197fac7a..e4ad9c71bb6 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -809,7 +809,7 @@ if ($action == 'edit') { if (getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail') == 'mail' && empty($conf->global->MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP)) { $messagetoshow = $langs->trans("WarningPHPMail").'
'.$langs->trans("WarningPHPMailA").'
'.$langs->trans("WarningPHPMailB").'
'.$langs->trans("WarningPHPMailC").'

'.$langs->trans("WarningPHPMailD"); $messagetoshow .= ' '.$langs->trans("WarningPHPMailDbis", '{s1}', '{s2}'); - $linktosetvar1 = ''; + $linktosetvar1 = ''; $linktosetvar2 = ''; $messagetoshow = str_replace('{s1}', $linktosetvar1, $messagetoshow); $messagetoshow = str_replace('{s2}', $linktosetvar2, $messagetoshow); diff --git a/htdocs/admin/mails_emailing.php b/htdocs/admin/mails_emailing.php index 1f638be3286..062aac55962 100644 --- a/htdocs/admin/mails_emailing.php +++ b/htdocs/admin/mails_emailing.php @@ -59,6 +59,16 @@ $substitutionarrayfortest = array( ); complete_substitutions_array($substitutionarrayfortest, $langs); +// List of sending methods +$listofmethods = array(); +$listofmethods['default'] = $langs->trans('DefaultOutgoingEmailSetup'); +$listofmethods['mail'] = 'PHP mail function'; +//$listofmethods['simplemail']='Simplemail class'; +$listofmethods['smtps'] = 'SMTP/SMTPS socket library'; +if (version_compare(phpversion(), '7.0', '>=')) { + $listofmethods['swiftmailer'] = 'Swift Mailer socket library'; +} + // Security check if (!$user->admin) { accessforbidden(); @@ -147,16 +157,6 @@ print load_fiche_titre($langs->trans("EMailsSetup"), '', 'title_setup'); $head = email_admin_prepare_head(); -// List of sending methods -$listofmethods = array(); -$listofmethods['default'] = $langs->trans('DefaultOutgoingEmailSetup'); -$listofmethods['mail'] = 'PHP mail function'; -//$listofmethods['simplemail']='Simplemail class'; -$listofmethods['smtps'] = 'SMTP/SMTPS socket library'; -if (version_compare(phpversion(), '7.0', '>=')) { - $listofmethods['swiftmailer'] = 'Swift Mailer socket library'; -} - // List of oauth services $oauthservices = array(); diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index dbf47365440..280a3b06247 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -334,7 +334,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { @@ -627,7 +627,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { print ''; print ""; + print ''; - print ''; + print '
'; } + print ''; + print '
'.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).''.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).''; + $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); + print $form->textwithpicto($langs->trans("Parameters"), $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); + print '
'; print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'minwidth150 maxwidth300', 1); print ''; - //print ''; - $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); - print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); + print ''; print ''; print '
'; if ($action == 'editoperation' && $ruleaction['id'] == $operationid) { - print '
'; + //print '
'; + print ''; print ''; print ''; print ''; } else { - print dol_escape_htmltag($ruleaction['actionparam']); + print dol_nl2br(dol_escape_htmltag($ruleaction['actionparam'], 0, 1)); } print '
'; $url = $_SERVER["PHP_SELF"].'?id='.$obj->rowid; if ($limit) { - $url .= '&limit='.urlencode($limit); + $url .= '&limit='.((int) $limit); } if ($page) { $url .= '&page='.urlencode($page); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 47e4939ef82..6dd34e990e7 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -93,7 +93,7 @@ $pageprev = $page - 1; $pagenext = $page + 1; if (empty($sortfield)) { - $sortfield = 'type_template, lang, position, label'; + $sortfield = 'type_template,lang,position,label'; } if (empty($sortorder)) { $sortorder = 'ASC'; @@ -109,21 +109,21 @@ $tabname[25] = MAIN_DB_PREFIX."c_email_templates"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield = array(); -$tabfield[25] = "label,lang,type_template,fk_user,private,position,module,topic,joinfiles,content"; +$tabfield[25] = "label,lang,type_template,fk_user,private,position,module,topic,joinfiles,defaultfortype,content"; if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tabfield[25] .= ',content_lines'; } // Nom des champs d'edition pour modification d'un enregistrement $tabfieldvalue = array(); -$tabfieldvalue[25] = "label,lang,type_template,fk_user,private,position,topic,joinfiles,content"; +$tabfieldvalue[25] = "label,lang,type_template,fk_user,private,position,topic,joinfiles,defaultfortype,content"; if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tabfieldvalue[25] .= ',content_lines'; } // Nom des champs dans la table pour insertion d'un enregistrement $tabfieldinsert = array(); -$tabfieldinsert[25] = "label,lang,type_template,fk_user,private,position,topic,joinfiles,content"; +$tabfieldinsert[25] = "label,lang,type_template,fk_user,private,position,topic,joinfiles,defaultfortype,content"; if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tabfieldinsert[25] .= ',content_lines'; } @@ -164,13 +164,14 @@ if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tabhelp = array(); $tabhelp[25] = array( 'label'=>$langs->trans('EnterAnyCode'), - 'topic'=>''.$helpsubstit.'', - 'joinfiles'=>$langs->trans('AttachMainDocByDefault'), - 'content'=>''.$helpsubstit.'', - 'content_lines'=>''.$helpsubstitforlines.'', 'type_template'=>$langs->trans("TemplateForElement"), 'private'=>$langs->trans("TemplateIsVisibleByOwnerOnly"), - 'position'=>$langs->trans("PositionIntoComboList") + 'position'=>$langs->trans("PositionIntoComboList"), + 'topic'=>''.$helpsubstit.'', + 'joinfiles'=>$langs->trans('AttachMainDocByDefault'), + 'defaultfortype'=>$langs->trans("DefaultForTypeDesc"), + 'content'=>''.$helpsubstit.'', + 'content_lines'=>''.$helpsubstitforlines.'' ); @@ -214,10 +215,10 @@ if (isModEnabled('ficheinter')) { if (isModEnabled('supplier_proposal')) { $elementList['supplier_proposal_send'] = img_picto('', 'propal', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierRequestForQuotation')); } -if ((isModEnabled("fournisseur") && !empty($user->rights->fournisseur->commande->lire) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (isModEnabled("supplier_order") && !empty($user->rights->supplier_order->lire))) { +if (isModEnabled("supplier_order") && ($user->hasRight('fournisseur', 'commande', 'lire') || $user->hasRight('supplier_order', 'read'))) { $elementList['order_supplier_send'] = img_picto('', 'order', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierOrder')); } -if ((isModEnabled("fournisseur") && !empty($user->rights->fournisseur->facture->lire) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || (isModEnabled("supplier_invoice") && !empty($user->rights->supplier_invoice->lire))) { +if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'read'))) { $elementList['invoice_supplier_send'] = img_picto('', 'bill', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierInvoice')); } if (isModEnabled('contrat') && !empty($user->rights->contrat->lire)) { @@ -307,7 +308,7 @@ if (empty($reshook)) { $ok = 1; foreach ($listfield as $f => $value) { // Not mandatory fields - if (in_array($value, ['joinfiles', 'content', 'content_lines', 'module'])) { + if (in_array($value, ['joinfiles', 'defaultfortype', 'content', 'content_lines', 'module'])) { continue; } @@ -383,6 +384,9 @@ if (empty($reshook)) { if ($value == 'position' && !is_numeric($_POST[$keycode])) { $_POST[$keycode] = '1'; } + if ($value == 'defaultfortype' && !is_numeric($_POST[$keycode])) { + $_POST[$keycode] = '0'; + } //var_dump($keycode.' '.$value); if ($i) { @@ -400,7 +404,7 @@ if (empty($reshook)) { } } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfiles', 'private', 'position', 'entity'))) { + } elseif (in_array($keycode, array('joinfiles', 'defaultfortype', 'private', 'position', 'entity'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'alphanohtml'))."'"; @@ -430,7 +434,7 @@ if (empty($reshook)) { // Modify entry $sql = "UPDATE ".$tabname[$id]." SET "; - // Modifie valeur des champs + // Modify value of fields $i = 0; foreach ($listfieldmodify as $field) { if ($field == 'entity') { @@ -449,20 +453,20 @@ if (empty($reshook)) { } // Rename some POST variables into a generic name - if ($field == 'fk_user' && !($_POST['fk_user'] > 0)) { + if ($field == 'fk_user' && !(GETPOST('fk_user', 'int') > 0)) { $_POST['fk_user'] = ''; } if ($field == 'topic') { - $_POST['topic'] = $_POST['topic-'.$rowid]; + $_POST['topic'] = GETPOST('topic-'.$rowid); } if ($field == 'joinfiles') { - $_POST['joinfiles'] = $_POST['joinfiles-'.$rowid]; + $_POST['joinfiles'] = GETPOST('joinfiles-'.$rowid); } if ($field == 'content') { - $_POST['content'] = $_POST['content-'.$rowid]; + $_POST['content'] = GETPOST('content-'.$rowid); } if ($field == 'content_lines') { - $_POST['content_lines'] = $_POST['content_lines-'.$rowid]; + $_POST['content_lines'] = GETPOST('content_lines-'.$rowid); } if ($i) { @@ -470,7 +474,7 @@ if (empty($reshook)) { } $sql .= $field."="; - if (GETPOST($keycode) == '' || ($keycode != 'langcode' && $keycode != 'position' && $keycode != 'private' && !GETPOST($keycode))) { + if (GETPOST($keycode) == '' || (!in_array($keycode, array('langcode', 'position', 'private', 'defaultfortype')) && !GETPOST($keycode))) { $sql .= "null"; // langcode,... must be '' if not defined so the unique key that include lang will work } elseif (GETPOST($keycode) == '0' && $keycode == 'langcode') { $sql .= "''"; // langcode must be '' if not defined so the unique key that include lang will work @@ -482,12 +486,11 @@ if (empty($reshook)) { } } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfiles', 'private', 'position'))) { + } elseif (in_array($keycode, array('joinfiles', 'defaultfortype', 'private', 'position'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'alphanohtml'))."'"; } - $i++; } @@ -572,7 +575,7 @@ if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu $morejs = array(); $morecss = array(); -$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, joinfiles, content_lines, content, enabled, active"; +$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, joinfiles, defaultfortype, content_lines, content, enabled, active"; $sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates"; $sql .= " WHERE entity IN (".getEntity('email_template').")"; if (!$user->admin) { @@ -623,7 +626,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if (!empty($search) && is_array($search)) { foreach ($search as $key => $val) { @@ -693,6 +696,7 @@ if ($action == 'create') { $obj->position = GETPOST('position'); $obj->topic = GETPOST('topic'); $obj->joinfiles = GETPOST('joinfiles'); + $obj->defaultfortype = GETPOST('defaultfortype') ? 1 : 0; $obj->content = GETPOST('content', 'restricthtml'); // Form to add a new line @@ -711,9 +715,9 @@ if ($action == 'create') { // dans les dictionnaires de donnees $valuetoshow = ucfirst($fieldlist[$field]); // Par defaut $valuetoshow = $langs->trans($valuetoshow); // try to translate - $align = "left"; + $css = "left"; if ($fieldlist[$field] == 'module') { - $valuetoshow = ''; + $valuetoshow = ' '; } if ($fieldlist[$field] == 'fk_user') { $valuetoshow = $langs->trans("Owner"); @@ -724,20 +728,20 @@ if ($action == 'create') { if ($fieldlist[$field] == 'type') { $valuetoshow = $langs->trans("Type"); } + if ($fieldlist[$field] == 'position') { + $css = 'center'; + } if ($fieldlist[$field] == 'code') { $valuetoshow = $langs->trans("Code"); } - if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { + if ($fieldlist[$field] == 'label') { $valuetoshow = $langs->trans("Code"); } if ($fieldlist[$field] == 'type_template') { - $valuetoshow = $langs->trans("TypeOfTemplate"); $align = "center"; + $valuetoshow = $langs->trans("TypeOfTemplate"); $css = "center"; } - if ($fieldlist[$field] == 'private') { - $align = 'center'; - } - if ($fieldlist[$field] == 'position') { - $align = 'center'; + if (in_array($fieldlist[$field], array('private', 'private', 'defaultfortype'))) { + $css = 'center'; } if ($fieldlist[$field] == 'topic') { @@ -753,7 +757,7 @@ if ($action == 'create') { $valuetoshow = ''; } if ($valuetoshow != '') { - print ''; + print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { @@ -793,19 +797,19 @@ if ($action == 'create') { fieldList($fieldlist, $obj, $tabname[$id], 'add'); } } - + // Action column print ''; print '
'; + // Show fields for topic, join files and body $fieldsforcontent = array('topic', 'joinfiles', 'content'); if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforcontent = array('topic', 'joinfiles', 'content', 'content_lines'); } foreach ($fieldsforcontent as $tmpfieldlist) { - print '
'; - // Topic of email if ($tmpfieldlist == 'topic') { print ''.$form->textwithpicto($langs->trans("Topic"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).' '; @@ -830,13 +834,14 @@ if ($action == 'create') { if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { $okforextended = false; } - $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : ''), '', 180, 'dolibarr_mailings', 'In', false, $acceptlocallinktomedia, $okforextended, ROWS_4, '90%'); + $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : ''), '', 400, 'dolibarr_mailings', 'In', false, $acceptlocallinktomedia, $okforextended, ROWS_6, '90%'); print $doleditor->Create(1); } - print '
'; if ($action != 'edit') { @@ -870,7 +875,7 @@ print ''; $i = 0; -$param = '&id='.$id; +$param = '&id='.((int) $id); if ($search_label) { $param .= '&search_label='.urlencode($search_label); } @@ -911,7 +916,13 @@ if ($num > $listlimit) { // Title line with search boxes print ''; - +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} foreach ($fieldlist as $field => $value) { if ($value == 'module') { print ''; @@ -935,23 +946,29 @@ foreach ($fieldlist as $field => $value) { print ''; } } - -if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { +/*if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { print ''; -} - +}*/ +// Status +print ''; // Action column -print ''; +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} print ''; // Title of lines print ''; +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList(''); +} foreach ($fieldlist as $field => $value) { $showfield = 1; // By defaut - $align = "left"; + $css = "left"; $sortable = 1; $valuetoshow = ''; $forcenowrap = 1; @@ -959,13 +976,13 @@ foreach ($fieldlist as $field => $value) { $tmparray=getLabelOfField($fieldlist[$field]); $showfield=$tmp['showfield']; $valuetoshow=$tmp['valuetoshow']; - $align=$tmp['align']; + $css=$tmp['align']; $sortable=$tmp['sortable']; */ $valuetoshow = ucfirst($fieldlist[$field]); // By defaut $valuetoshow = $langs->trans($valuetoshow); // try to translate if ($fieldlist[$field] == 'module') { - $align = 'tdoverflowmax100'; + $css = 'tdoverflowmax100'; } if ($fieldlist[$field] == 'fk_user') { $valuetoshow = $langs->trans("Owner"); @@ -980,18 +997,20 @@ foreach ($fieldlist as $field => $value) { $valuetoshow = $langs->trans("Code"); } if ($fieldlist[$field] == 'type_template') { - $align = 'center'; + $css = 'center'; $valuetoshow = $langs->trans("TypeOfTemplate"); } if ($fieldlist[$field] == 'private') { - $align = 'center'; + $css = 'center'; } if ($fieldlist[$field] == 'position') { - $align = 'center'; + $css = 'center'; } if ($fieldlist[$field] == 'joinfiles') { - $valuetoshow = $langs->trans("FilesAttachedToEmail"); $align = 'center'; $forcenowrap = 0; + $valuetoshow = $langs->trans("FilesAttachedToEmail"); + $css = 'center'; + $forcenowrap = 0; } if ($fieldlist[$field] == 'content') { $valuetoshow = $langs->trans("Content"); $showfield = 0; @@ -1011,14 +1030,17 @@ foreach ($fieldlist as $field => $value) { } $sortfieldtouse = ($sortable ? $fieldlist[$field] : ''); if ($sortfieldtouse == 'type_template') { - $sortfieldtouse.= ',label'; + $sortfieldtouse.= 'type_template,lang,position,label'; } - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], $sortfieldtouse, ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $align.' '); + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], $sortfieldtouse, ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $css.' '); } } print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, 'center '); -print getTitleFieldOfList(''); +// Action column +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList(''); +} print ''; if ($num) { @@ -1037,42 +1059,57 @@ if ($num) { $reshook = $hookmanager->executeHooks('editEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $error = $hookmanager->error; $errors = $hookmanager->errors; + // Action column + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } // Show main fields if (empty($reshook)) { fieldList($fieldlist, $obj, $tabname[$id], 'edit'); } + // Action column + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + print "\n"; - print ''; - print ''; + print ''; + print ''; - print ''; - print ''; - print ''; } } + print ''; + print ''; + print ''; print "\n"; @@ -1125,8 +1163,34 @@ if ($num) { $nbqualified++; + // Can an entry be erased or disabled ? + $iserasable = 1; $canbedisabled = 1; $canbemodified = 1; // true by default + if (!$user->admin && $obj->fk_user != $user->id) { + $iserasable = 0; + $canbedisabled = 0; + $canbemodified = 0; + } + + $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); + if ($param) { + $url .= '&'.$param; + } + print ''; + // Action column - Modify link / Delete link + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + $tmpaction = 'view'; $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); $reshook = $hookmanager->executeHooks('viewEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks @@ -1139,7 +1203,7 @@ if ($num) { continue; } $showfield = 1; - $align = ""; + $css = ""; $class = "tddict"; $title = ''; $tmpvar = $fieldlist[$field]; @@ -1158,7 +1222,7 @@ if ($num) { } if ($value == 'type_template') { $valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow; - $align = "center"; + $css = "center"; } if ($value == 'lang' && $valuetoshow) { $valuetoshow = $valuetoshow.' - '.$langs->trans("Language_".$valuetoshow); @@ -1171,7 +1235,7 @@ if ($num) { } } if ($value == 'private') { - $align = "center"; + $css = "center"; if ($valuetoshow) { $valuetoshow = yn($valuetoshow); } else { @@ -1179,18 +1243,18 @@ if ($num) { } } if ($value == 'position') { - $align = "center"; + $css = "center"; } - if ($value == 'joinfiles') { - $align = "center"; + if (in_array($value, array('joinfiles', 'defaultfortype'))) { + $css = "center"; if ($valuetoshow) { $valuetoshow = yn(1); } else { $valuetoshow = ''; } } - if ($align) { - $class .= ' '.$align; + if ($css) { + $class .= ' '.$css; } // Show value for field @@ -1207,19 +1271,6 @@ if ($num) { } } - // Can an entry be erased or disabled ? - $iserasable = 1; $canbedisabled = 1; $canbemodified = 1; // true by default - if (!$user->admin && $obj->fk_user != $user->id) { - $iserasable = 0; - $canbedisabled = 0; - $canbemodified = 0; - } - - $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); - if ($param) { - $url .= '&'.$param; - } - // Status / Active print '"; - // Modify link / Delete link - print ''; } - if ($iserasable) { - print ''.img_delete().''; - //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin - } - print ''; print "\n"; } @@ -1288,6 +1341,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $formadmin = new FormAdmin($db); foreach ($fieldlist as $field => $value) { + //print $value; if ($value == 'module') { print ''; } elseif ($value == 'fk_user') { @@ -1343,11 +1397,11 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } print ''; } elseif ($context == 'add' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) { - continue; + //print ''; } elseif ($context == 'edit' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) { - continue; + print ''; } elseif ($context == 'hide' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) { - continue; + //print ''; } else { $size = ''; $class = ''; $classtd = ''; if ($value == 'code') { @@ -1357,19 +1411,19 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $class = 'maxwidth200'; } if ($value == 'private') { - $class = 'maxwidth50'; $classtd = 'center'; + $class = 'maxwidth50'; + $classtd = 'center'; } if ($value == 'position') { - $class = 'maxwidth50 center'; $classtd = 'center'; - } - if ($value == 'libelle') { - $class = 'quatrevingtpercent'; + $class = 'maxwidth50 center'; + $classtd = 'center'; } if ($value == 'topic') { $class = 'quatrevingtpercent'; } - if ($value == 'sortorder' || $value == 'sens' || $value == 'category_type') { - $size = 'size="2" '; + if ($value == 'defaultfortype') { + $class = 'width25 center'; + $classtd = 'center'; } print ''; @@ -1377,10 +1431,10 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if (empty($user->admin)) { print $form->selectyesno($value, '1', 1); } else { - print $form->selectyesno($value, (isset($obj->{$value}) ? $obj->{$value}:''), 1); + print $form->selectyesno($value, (isset($obj->$value) ? $obj->$value : ''), 1); } } else { - print ''; + print ''; } print ''; } diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 1af4b25bb27..05b76c9d6d5 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -369,14 +369,32 @@ if ($mode == 'desc') { if ($mode == 'feature') { $text .= '
'.$langs->trans("DependsOn").': '; - if (count($objMod->depends)) { - $text .= join(',', $objMod->depends); + if (is_array($objMod->depends) && count($objMod->depends)) { + $i = 0; + foreach ($objMod->depends as $modulestringorarray) { + if (is_array($modulestringorarray)) { + $text .= ($i ? ', ' : '').join(', ', $modulestringorarray); + } else { + $text .= ($i ? ', ' : '').$modulestringorarray; + } + $i++; + } } else { $text .= ''.$langs->trans("None").''; } + $text .= '
'; + $text .= '
'.$langs->trans("RequiredBy").': '; - if (count($objMod->requiredby)) { - $text .= join(',', $objMod->requiredby); + if (is_array($objMod->requiredby) && count($objMod->requiredby)) { + $i = 0; + foreach ($objMod->requiredby as $modulestringorarray) { + if (is_array($modulestringorarray)) { + $text .= ($i ? ', ' : '').join(', ', $modulestringorarray); + } else { + $text .= ($i ? ', ' : '').$modulestringorarray; + } + $i++; + } } else { $text .= ''.$langs->trans("None").''; } @@ -478,7 +496,7 @@ if ($mode == 'feature') { if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) { $yesno = 'Yes'; } else { - $yesno = 'No'; + $yesno = 'No'; } require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php'; $interfaces = new Interfaces($db); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 68bec8431a7..f5ec91027f8 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -231,7 +231,7 @@ if ($action == 'install') { if (!$error) { @dol_delete_dir_recursive($dirins.'/'.$modulenameval); // delete the target directory $submodulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulenameval; - if (!dol_is_dir($modulenamedir)) { + if (!dol_is_dir($submodulenamedir)) { $submodulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulenameval; } dol_syslog("We copy now directory ".$submodulenamedir." into target dir ".$dirins.'/'.$modulenameval); @@ -476,7 +476,7 @@ foreach ($modulesdir as $dir) { dol_syslog("Module ".get_class($objMod)." not qualified"); } } else { - print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)
"; + print "admin/modules.php Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)
"; } } catch (Exception $e) { dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR); @@ -1165,7 +1165,7 @@ if ($mode == 'deploy') { $fullurl = ''.$urldolibarrmodules.''; $message = ''; - if (!empty($allowonlineinstall)) { + if ($allowonlineinstall) { if (!in_array('/custom', explode(',', $dolibarr_main_url_root_alt))) { $message = info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT)); $allowfromweb = -1; @@ -1184,7 +1184,7 @@ if ($mode == 'deploy') { } else { if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) { // Show clean message - if (!is_numeric('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) { + if (!is_numeric(getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US'))) { $message = info_admin($langs->trans(getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US'))); } else { $message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs')); diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index f86f6d5c27f..7893b271d06 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -188,7 +188,7 @@ print '
'; //USTRD print ''; print ''; +print ''; print ''; */ diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index a8ae4501ca5..f515ea56600 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -317,6 +317,7 @@ if ($mode == 'config' && $user->admin) { print ''; print ''; print "\n"; + $ret = $printer->listprinters(); $nbofprinters = count($printer->listprinters); diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 7a7e49a3129..211996712a9 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -181,16 +181,25 @@ $formproduct = new FormProduct($db); $disabled = ''; if (isModEnabled('productbatch')) { + // If module lot/serial enabled, we force the inc/dec mode to STOCK_CALCULATE_ON_SHIPMENT_CLOSE and STOCK_CALCULATE_ON_RECEPTION_CLOSE $langs->load("productbatch"); $disabled = ' disabled'; - print info_admin($langs->trans("WhenProductBatchModuleOnOptionAreForced")); + + // STOCK_CALCULATE_ON_SHIPMENT_CLOSE + $descmode = $langs->trans('DeStockOnShipmentOnClosing'); + if (!isModEnabled('reception')) { + // STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER + $incmode = $langs->trans('ReStockOnDispatchOrder'); + } else { + // STOCK_CALCULATE_ON_RECEPTION_CLOSE + $incmode = $langs->trans('StockOnReceptionOnClosing'); + } + print info_admin($langs->trans("WhenProductBatchModuleOnOptionAreForced", $descmode, $incmode)); } -//if (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) -//{ + print info_admin($langs->trans("IfYouUsePointOfSaleCheckModule")); print '
'; -//} print ''; @@ -221,7 +230,7 @@ if (isModEnabled('facture')) { print $form->selectarray("STOCK_CALCULATE_ON_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_BILL); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module30Name")).''; } print "\n\n"; $found++; @@ -242,7 +251,7 @@ if (isModEnabled('commande')) { print $form->selectarray("STOCK_CALCULATE_ON_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module25Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module25Name")).''; } print "\n\n"; $found++; @@ -261,7 +270,7 @@ if (isModEnabled("expedition")) { print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT", $arrval, $conf->global->STOCK_CALCULATE_ON_SHIPMENT); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).''; } print "\n\n"; $found++; @@ -278,7 +287,7 @@ if (isModEnabled("expedition")) { print $form->selectarray("STOCK_CALCULATE_ON_SHIPMENT_CLOSE", $arrval, $conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module80Name")).''; } print "\n\n"; $found++; @@ -301,7 +310,7 @@ $found = 0; print ''; print ''; print '\n\n"; $found++; @@ -323,7 +332,7 @@ $found++; print ''; print ''; print '\n\n"; $found++; @@ -372,7 +381,7 @@ if (isModEnabled("reception")) { print ''; print ''; print '\n\n"; $found++; diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php index fd586e24c95..10301bf3aed 100644 --- a/htdocs/admin/system/perf.php +++ b/htdocs/admin/system/perf.php @@ -424,7 +424,7 @@ print '
'; print ''.$langs->trans("HTTPCacheStaticResources").' - '; print $form->textwithpicto($langs->trans("CacheByServer"), $langs->trans("CacheByServerDesc")); print ':
'; -// No cahce on PHP +// No cache on PHP //print '
'.img_picto('','warning.png').' '.$langs->trans("FilesOfTypeNotCompressed",'php (.php)').'
'; //print '
'.img_picto('','tick.png').' '.$langs->trans("FilesOfTypeNotCached",'php (.php)').'
'; // Cache on rest diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 15db7d2ba0d..4229a6def80 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -173,7 +173,7 @@ print '
'; print ''.$langs->trans("XDebug").': '; $test = !function_exists('xdebug_is_enabled') && !extension_loaded('xdebug'); if ($test) { - print img_picto('', 'tick.png').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); + print img_picto('', 'tick').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); } else { print img_picto('', 'warning').' '.$langs->trans("ModuleActivatedMayExposeInformation", $langs->transnoentities("XDebug")); print ' - '.$langs->trans("MoreInformation").' XDebug admin page'; @@ -480,30 +480,57 @@ print load_fiche_titre($langs->trans("Modules"), '', 'folder'); // Module log print ''.$langs->trans("Syslog").': '; -$test = !isModEnabled('syslog'); -if ($test) { - print img_picto('', 'tick.png').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); +$test = isModEnabled('syslog'); +if (!$test) { + print img_picto('', 'tick').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); } else { if (getDolGlobalInt('SYSLOG_LEVEL') > LOG_NOTICE) { print img_picto('', 'warning').' '.$langs->trans("ModuleActivatedWithTooHighLogLevel", $langs->transnoentities("Syslog")); } else { - print img_picto('', 'tick.png').' '.$langs->trans("ModuleSyslogActivatedButLevelNotTooVerbose", $langs->transnoentities("Syslog"), getDolGlobalInt('SYSLOG_LEVEL')); + print img_picto('', 'tick').' '.$langs->trans("ModuleSyslogActivatedButLevelNotTooVerbose", $langs->transnoentities("Syslog"), getDolGlobalInt('SYSLOG_LEVEL')); } //print ' '.$langs->trans("MoreInformation").' XDebug admin page'; } print '
'; +print '
'; + // Module debugbar print ''.$langs->trans("DebugBar").': '; -$test = empty($conf->debugbar->enabled); -if ($test) { - print img_picto('', 'tick.png').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); +$test = isModEnabled('debugbar'); +if (!$test) { + print img_picto('', 'tick').' '.$langs->trans("NotInstalled").' - '.$langs->trans("NotRiskOfLeakWithThis"); } else { print img_picto('', 'error').' '.$langs->trans("ModuleActivatedDoNotUseInProduction", $langs->transnoentities("DebugBar")); //print ' '.$langs->trans("MoreInformation").' XDebug admin page'; } print '
'; +print '
'; + +// Modules for Payments +$test = isModEnabled('stripe'); +if ($test) { + print ''.$langs->trans("Stripe").': '; + if (!getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) { + print img_picto('', 'error').' '.$langs->trans("OptionXShouldBeEnabledInModuleY", $langs->transnoentities("SecurityTokenIsUnique"), $langs->transnoentities("Stripe")); + } else { + print img_picto('', 'tick').' '.$langs->trans("OptionXIsCorrectlyEnabledInModuleY", $langs->transnoentities("SecurityTokenIsUnique"), $langs->transnoentities("Stripe")); + } + print '
'; +} else { + $test = isModEnabled('paypal'); + if ($test) { + print ''.$langs->trans("Paypal").': '; + if (!getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) { + print img_picto('', 'error').' '.$langs->trans("OptionXShouldBeEnabledInModuleY", $langs->transnoentities("SecurityTokenIsUnique"), $langs->transnoentities("Paypal")); + } else { + print img_picto('', 'tick').' '.$langs->trans("OptionXIsCorrectlyEnabledInModuleY", $langs->transnoentities("SecurityTokenIsUnique"), $langs->transnoentities("Paypal")); + } + print '
'; + } +} + // APIs @@ -601,6 +628,9 @@ print '
'; print 'MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = '.getDolGlobalString('MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES', ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)')."
"; print '
'; +print 'MAIN_DISALLOW_EXT_URL_INTO_DESCRIPTIONS = '.getDolGlobalString('MAIN_DISALLOW_EXT_URL_INTO_DESCRIPTIONS', ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)')."
"; +print '
'; + print 'MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL = '.getDolGlobalString('MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL', ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)')."
"; print '
'; diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php index 3e04243eb72..045ecda2cc7 100644 --- a/htdocs/admin/tools/listevents.php +++ b/htdocs/admin/tools/listevents.php @@ -259,7 +259,7 @@ if ($result) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index fcbc01abef1..6013ae41e94 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -226,7 +226,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if (isset($optioncss) && $optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index cf55c7b9127..28d347bcabe 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -122,7 +122,7 @@ $workflowcodes = array( 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL'=>array( 'family'=>'classify_supplier_proposal', 'position'=>60, - 'enabled'=>(isModEnabled('supplier_proposal') && ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), + 'enabled'=>(isModEnabled('supplier_proposal') && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 'picto'=>'supplier_proposal', 'warning'=>'' ), @@ -131,7 +131,7 @@ $workflowcodes = array( 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION'=>array( 'family'=>'classify_supplier_order', 'position'=>63, - 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (isModEnabled("reception")) && ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !isModEnabled('supplier_order'))), + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && isModEnabled("reception") && isModEnabled('supplier_order')), 'picto'=>'supplier_order', 'warning'=>'' ), @@ -139,7 +139,7 @@ $workflowcodes = array( 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED'=>array( 'family'=>'classify_supplier_order', 'position'=>64, - 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (isModEnabled("reception")) && ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !isModEnabled('supplier_order'))), + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && isModEnabled("reception") && isModEnabled('supplier_order')), 'picto'=>'supplier_order', 'warning'=>'' ), @@ -147,7 +147,7 @@ $workflowcodes = array( 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array( 'family'=>'classify_supplier_order', 'position'=>65, - 'enabled'=>((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")), + 'enabled'=>(isModEnabled("supplier_order") || isModEnabled("supplier_invoice")), 'picto'=>'supplier_order', 'warning'=>'' ), @@ -164,7 +164,7 @@ $workflowcodes = array( 'WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE'=>array( 'family'=>'classify_reception', 'position'=>95, - 'enabled'=>(isModEnabled("reception") && ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), + 'enabled'=>(isModEnabled("reception") && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 'picto'=>'reception' ), diff --git a/htdocs/asset/agenda.php b/htdocs/asset/agenda.php index 166eb12935c..ef9afa10458 100644 --- a/htdocs/asset/agenda.php +++ b/htdocs/asset/agenda.php @@ -197,7 +197,7 @@ if ($object->id > 0) { $param .= '&contextpage=' . urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit=' . urlencode($limit); + $param .= '&limit='.((int) $limit); } diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index 4b3b530148d..8f8c551d66b 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -354,7 +354,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/asset/model/agenda.php b/htdocs/asset/model/agenda.php index 51a55e0e144..44a0fa504a3 100644 --- a/htdocs/asset/model/agenda.php +++ b/htdocs/asset/model/agenda.php @@ -199,7 +199,7 @@ if ($object->id > 0) { // $param .= '&contextpage=' . urlencode($contextpage); // } // if ($limit > 0 && $limit != $conf->liste_limit) { - // $param .= '&limit=' . urlencode($limit); + // $param .= '&limit='.((int) $limit); // } // // diff --git a/htdocs/asset/model/list.php b/htdocs/asset/model/list.php index 51e45f244d0..8ccf50a8ab1 100644 --- a/htdocs/asset/model/list.php +++ b/htdocs/asset/model/list.php @@ -360,7 +360,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index b3b2a1d36f4..8d03c029cd6 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -325,7 +325,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_id != '') { $param .= '&search_id='.urlencode($search_id); @@ -550,7 +550,10 @@ if (is_array($blocks)) { print ''; // Link to source object - print ''.$object_link.''; + print ''; diff --git a/htdocs/bom/bom_agenda.php b/htdocs/bom/bom_agenda.php index ddd57d34e76..5e25d788ac7 100644 --- a/htdocs/bom/bom_agenda.php +++ b/htdocs/bom/bom_agenda.php @@ -241,7 +241,7 @@ if ($object->id > 0) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index e27cd0a2e1c..10fc6c3030d 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -170,6 +170,13 @@ if (empty($reshook)) { $disable_stock_change = GETPOST('disable_stock_change', 'int'); $efficiency = price2num(GETPOST('efficiency', 'alpha')); $fk_unit = GETPOST('fk_unit', 'alphanohtml'); + + if (!empty($idprod) && $conf->workstation->enabled) { + $product = new Product($db); + $res = $product->fetch($idprod); + if ($res > 0 && $product->type == Product::TYPE_SERVICE) $fk_default_workstation = $product->fk_default_workstation; + } + if ($qty == '') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; @@ -206,7 +213,7 @@ if (empty($reshook)) { } } - $result = $object->addLine($idprod, $qty, $qty_frozen, $disable_stock_change, $efficiency, -1, $bom_child_id, null, $fk_unit, $array_options); + $result = $object->addLine($idprod, $qty, $qty_frozen, $disable_stock_change, $efficiency, -1, $bom_child_id, null, $fk_unit, $array_options, $fk_default_workstation); if ($result <= 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -566,7 +573,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!empty($object->table_element_line)) { // Products - $res = $object->fetchLinesbytypeproduct(0); + $res = $object->fetchLinesbytypeproduct(0); // Load all lines products into ->lines $object->calculateCosts(); print ($res == 0 && $object->status >= $object::STATUS_VALIDATED) ? '' : load_fiche_titre($langs->trans('BOMProductsList'), '', 'product'); @@ -615,7 +622,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Services $filtertype = 1; - $res = $object->fetchLinesbytypeproduct(1); + $res = $object->fetchLinesbytypeproduct(1); // Load all lines services into ->lines $object->calculateCosts(); print ($res == 0 && $object->status >= $object::STATUS_VALIDATED) ? '' : load_fiche_titre($langs->trans('BOMServicesList'), '', 'service'); diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 065a3a578b7..0819c4f1cd1 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -442,7 +442,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key])) { diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 45cbfdef383..b54eb38ebd4 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -227,7 +227,6 @@ class BOM extends CommonObject public $unit_cost = 0; - /** * Constructor * @@ -569,10 +568,11 @@ class BOM extends CommonObject * @param int $fk_bom_child Id of BOM Child * @param string $import_key Import Key * @param string $fk_unit Unit - * @param array $array_options extrafields array + * @param array $array_options extrafields array + * @param int $fk_default_workstation Default workstation * @return int <0 if KO, Id of created object if OK */ - public function addLine($fk_product, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $fk_bom_child = null, $import_key = null, $fk_unit = '', $array_options = 0) + public function addLine($fk_product, $qty, $qty_frozen = 0, $disable_stock_change = 0, $efficiency = 1.0, $position = -1, $fk_bom_child = null, $import_key = null, $fk_unit = '', $array_options = 0, $fk_default_workstation = null) { global $mysoc, $conf, $langs, $user; @@ -627,33 +627,34 @@ class BOM extends CommonObject } // Insert line - $this->line = new BOMLine($this->db); + $line = new BOMLine($this->db); - $this->line->context = $this->context; + $line->context = $this->context; - $this->line->fk_bom = $this->id; - $this->line->fk_product = $fk_product; - $this->line->qty = $qty; - $this->line->qty_frozen = $qty_frozen; - $this->line->disable_stock_change = $disable_stock_change; - $this->line->efficiency = $efficiency; - $this->line->fk_bom_child = $fk_bom_child; - $this->line->import_key = $import_key; - $this->line->position = $rankToUse; - $this->line->fk_unit = $fk_unit; + $line->fk_bom = $this->id; + $line->fk_product = $fk_product; + $line->qty = $qty; + $line->qty_frozen = $qty_frozen; + $line->disable_stock_change = $disable_stock_change; + $line->efficiency = $efficiency; + $line->fk_bom_child = $fk_bom_child; + $line->import_key = $import_key; + $line->position = $rankToUse; + $line->fk_unit = $fk_unit; + $line->fk_default_workstation = $fk_default_workstation; if (is_array($array_options) && count($array_options) > 0) { - $this->line->array_options = $array_options; + $line->array_options = $array_options; } - $result = $this->line->create($user); + $result = $line->create($user); if ($result > 0) { $this->calculateCosts(); $this->db->commit(); return $result; } else { - $this->error = $this->line->error; + $this->setErrorsFromObject($line); dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); $this->db->rollback(); return -2; @@ -722,8 +723,7 @@ class BOM extends CommonObject $staticLine = clone $line; $line->oldcopy = $staticLine; - $this->line = $line; - $this->line->context = $this->context; + $line->context = $this->context; // Rank to use $rankToUse = (int) $position; @@ -741,32 +741,32 @@ class BOM extends CommonObject } - $this->line->fk_bom = $this->id; - $this->line->qty = $qty; - $this->line->qty_frozen = $qty_frozen; - $this->line->disable_stock_change = $disable_stock_change; - $this->line->efficiency = $efficiency; - $this->line->import_key = $import_key; - $this->line->position = $rankToUse; + $line->fk_bom = $this->id; + $line->qty = $qty; + $line->qty_frozen = $qty_frozen; + $line->disable_stock_change = $disable_stock_change; + $line->efficiency = $efficiency; + $line->import_key = $import_key; + $line->position = $rankToUse; if (!empty($fk_unit)) { - $this->line->fk_unit = $fk_unit; + $line->fk_unit = $fk_unit; } if (is_array($array_options) && count($array_options) > 0) { // We replace values in this->line->array_options only for entries defined into $array_options foreach ($array_options as $key => $value) { - $this->line->array_options[$key] = $array_options[$key]; + $line->array_options[$key] = $array_options[$key]; } } - $result = $this->line->update($user); + $result = $line->update($user); if ($result > 0) { $this->calculateCosts(); $this->db->commit(); return $result; } else { - $this->error = $this->line->error; + $this->setErrorsFromObject($line); dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); $this->db->rollback(); return -2; @@ -801,10 +801,9 @@ class BOM extends CommonObject $staticLine = clone $line; $line->oldcopy = $staticLine; - $this->line = $line; - $this->line->context = $this->context; + $line->context = $this->context; - $result = $this->line->delete($user, $notrigger); + $result = $line->delete($user, $notrigger); //Positions (rank) reordering foreach ($this->lines as $bl) { @@ -819,7 +818,7 @@ class BOM extends CommonObject $this->db->commit(); return $result; } else { - $this->error = $this->line->error; + $this->setErrorsFromObject($line); dol_syslog(get_class($this)."::addLine error=".$this->error, LOG_ERR); $this->db->rollback(); return -2; @@ -1168,7 +1167,7 @@ class BOM extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; @@ -1423,21 +1422,32 @@ class BOM extends CommonObject } } } else { - //Convert qty to hour - $unit = measuringUnitString($line->fk_unit, '', '', 1); - $qty = convertDurationtoHour($line->qty, $unit); + // Convert qty of line into hours + $unitforline = measuringUnitString($line->fk_unit, '', '', 1); + $qtyhourforline = convertDurationtoHour($line->qty, $unitforline); if (isModEnabled('workstation') && !empty($tmpproduct->fk_default_workstation)) { $workstation = new Workstation($this->db); $res = $workstation->fetch($tmpproduct->fk_default_workstation); - if ($res > 0) $line->total_cost = price2num($qty * ($workstation->thm_operator_estimated + $workstation->thm_machine_estimated), 'MT'); + if ($res > 0) $line->total_cost = price2num($qtyhourforline * ($workstation->thm_operator_estimated + $workstation->thm_machine_estimated), 'MT'); else { $this->error = $workstation->error; return -3; } } else { - $line->total_cost = price2num($qty * $tmpproduct->cost_price, 'MT'); + $defaultdurationofservice = $tmpproduct->duration; + $reg = array(); + $qtyhourservice = 0; + if (preg_match('/^(\d+)([a-z]+)$/', $defaultdurationofservice, $reg)) { + $qtyhourservice = convertDurationtoHour($reg[1], $reg[2]); + } + + if ($qtyhourservice) { + $line->total_cost = price2num($qtyhourforline / $qtyhourservice * $tmpproduct->cost_price, 'MT'); + } else { + $line->total_cost = price2num($line->qty * $tmpproduct->cost_price, 'MT'); + } } $this->total_cost += $line->total_cost; @@ -1670,6 +1680,7 @@ class BOMLine extends CommonObjectLine 'fk_unit' => array('type'=>'integer', 'label'=>'Unit', 'enabled'=>1, 'visible'=>1, 'position'=>120, 'notnull'=>-1,), 'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), + 'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>1050) ); /** @@ -1732,6 +1743,12 @@ class BOMLine extends CommonObjectLine */ public $childBom = array(); + /** + * @var int Service Workstation + */ + public $fk_default_workstation; + + /** * Constructor diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 0d49937e6d2..69928c2545a 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -196,10 +196,6 @@ if ($filtertype != 1) { print ''; print ''; - -if (is_object($objectline)) { - print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1, 'line'); -} ?> '; @@ -298,16 +268,18 @@ print ''; print ''; print ''; print ''; -//print ''; +print ''; print ''; for ($i = 1 ; $i < $MAXLINES; $i++) { $label = ''; $amount = ''; + $amounto = ''; if ($errori[$i]) { $label = GETPOST($i.'_label', 'alpha'); $amount = GETPOST($i.'_amount', 'alpha'); + $amountto = GETPOST($i.'_amountto', 'alpha'); } if ($i == 1) { @@ -339,11 +311,14 @@ for ($i = 1 ; $i < $MAXLINES; $i++) { print $form->selectDate((!empty($dateo[$i]) ? $dateo[$i] : ''), $i.'_', '', '', '', 'add'); print "\n"; + // Description print ''; + // Amount print ''; - print ''; + // AmountToOthercurrency + print ''; print ''; } @@ -352,7 +327,7 @@ print '
'; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print ''; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'; + print ''; + print ''; + print ''; + print '
'; + print ''; + print '
'; + print ''; + print ''; + print ''; + print '
'; + print ''; + print '
'; - print ''; - print ''; - print ''; - print '
'; - print ''; - print '
'; $fieldsforcontent = array('topic', 'joinfiles', 'content'); if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { - $fieldsforcontent = array('topic', 'joinfiles', 'content', 'content_lines'); + $fieldsforcontent[] = 'content_lines'; } foreach ($fieldsforcontent as $tmpfieldlist) { $showfield = 1; - $align = "left"; + $css = "left"; $valuetoshow = $obj->$tmpfieldlist; $class = 'tddict'; // Show value for field if ($showfield) { // Show line for topic, joinfiles and content - print '
'; if ($tmpfieldlist == 'topic') { print ''.$form->textwithpicto($langs->trans("Topic"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).' '; print ''; + print '
'."\n"; } if ($tmpfieldlist == 'joinfiles') { print ''.$form->textwithpicto($langs->trans("FilesAttachedToEmail"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).' '; print $form->selectyesno($tmpfieldlist.'-'.$rowid, (isset($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : '0'), 1, false, 0, 1); + print '
'."\n"; } if ($tmpfieldlist == 'content') { @@ -1085,6 +1122,7 @@ if ($num) { print $doleditor->Create(1); } if ($tmpfieldlist == 'content_lines') { + print '
'."\n"; print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; $okforextended = true; if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { @@ -1093,11 +1131,11 @@ if ($num) { $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, $acceptlocallinktomedia, $okforextended, ROWS_6, '90%'); print $doleditor->Create(1); } - print '
'; + if ($canbemodified) { + print ''.img_edit().''; + } + if ($iserasable) { + print ''.img_delete().''; + //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin + } + print ''; if ($canbedisabled) { @@ -1229,16 +1280,18 @@ if ($num) { } print "'; - if ($canbemodified) { - print ''.img_edit().''; + // Action column - Modify link / Delete link + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if ($canbemodified) { + print ''.img_edit().''; + } + if ($iserasable) { + print ''.img_delete().''; + //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin + } + print '
'.$langs->trans("USTRD").''; -print '
'.$langs->trans("Parameters").'
'.$langs->trans("ReStockOnBill").''; -if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { +if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { if ($conf->use_javascript_ajax) { if ($disabled) { print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"'); @@ -313,7 +322,7 @@ if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMO print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_BILL", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).''; } print "
'.$langs->trans("ReStockOnValidateOrder").''; -if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { +if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { if ($conf->use_javascript_ajax) { if ($disabled) { print img_picto($langs->trans("Disabled"), 'off', 'class="opacitymedium"'); @@ -335,7 +344,7 @@ if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMO print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).''; } print "
'.$langs->trans("ReStockOnDispatchOrder").''; - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order")) { + if (isModEnabled("supplier_order")) { if ($conf->use_javascript_ajax) { print ajax_constantonoff('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER', array(), null, 0, 0, 0, 2, 1, '', '', 'reposition'); } else { @@ -380,7 +389,7 @@ if (isModEnabled("reception")) { print $form->selectarray("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $arrval, $conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER); } } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")); + print ''.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")).''; } print "
'; + print ''; // $object_link can be a ''; // Amount print ''.price($block->amounts).'
'.$langs->trans("Type").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").''.$langs->trans("AmountToOthercurrency").''.$langs->trans("AmountToOthercurrency").'
'; print '
'; print ''; print '
'; -print ' +print ' '; diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php index d72238e3fe6..ec703f3fea4 100644 --- a/htdocs/compta/bank/various_payment/list.php +++ b/htdocs/compta/bank/various_payment/list.php @@ -351,7 +351,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 1333a6b2346..4451707bdff 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -348,7 +348,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key])) { diff --git a/htdocs/compta/deplacement/class/deplacement.class.php b/htdocs/compta/deplacement/class/deplacement.class.php index fa812a14c3d..c0254f6c316 100644 --- a/htdocs/compta/deplacement/class/deplacement.class.php +++ b/htdocs/compta/deplacement/class/deplacement.class.php @@ -338,10 +338,10 @@ class Deplacement extends CommonObject /** - * Retourne le libelle du statut + * Return the label of the status * - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto - * @return string Libelle + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -350,11 +350,11 @@ class Deplacement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto - * @return string Libelle + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function LibStatut($status, $mode = 0) { diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php index 4cb75c526ef..38e00a2c68b 100644 --- a/htdocs/compta/deplacement/stats/index.php +++ b/htdocs/compta/deplacement/stats/index.php @@ -242,9 +242,8 @@ print ''; print ''; // Company print ''; // User print ''; print '\n"; - //$out.=''; } // From @@ -590,15 +588,16 @@ class FormMail extends Form // Add user email if (empty($user->email)) { $langs->load('errors'); - $liste['user'] = $user->getFullName($langs).' <'.$langs->trans('ErrorNoMailDefinedForThisUser').'>'; + $s = $user->getFullName($langs).' <'.$langs->trans('ErrorNoMailDefinedForThisUser').'>'; } else { - $liste['user'] = $user->getFullName($langs).' <'.$user->email.'>'; + $s = $user->getFullName($langs).' <'.$user->email.'>'; } + $liste['user'] = array('label' => $s, 'data-html' => $s); // Add also company main email if (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { - $liste['company'] = !empty($conf->global->MAIN_INFO_SOCIETE_NOM)?$conf->global->MAIN_INFO_SOCIETE_NOM:$conf->global->MAIN_INFO_SOCIETE_MAIL; - $liste['company'].=' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>'; + $s = (empty($conf->global->MAIN_INFO_SOCIETE_NOM)?$conf->global->MAIN_INFO_SOCIETE_EMAIL:$conf->global->MAIN_INFO_SOCIETE_NOM).' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>'; + $liste['company'] = array('label' => $s, 'data-html' => $s); } // Add also email aliases if there is some @@ -610,10 +609,11 @@ class FormMail extends Form // Also add robot email if (!empty($this->fromalsorobot)) { if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { - $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM; + $s = $conf->global->MAIN_MAIL_EMAIL_FROM; if ($this->frommail) { - $liste['robot'] .= ' <'.$conf->global->MAIN_MAIL_EMAIL_FROM.'>'; + $s .= ' <'.$conf->global->MAIN_MAIL_EMAIL_FROM.'>'; } + array('label' => $s, 'data-html' => $s); } } @@ -648,7 +648,7 @@ class FormMail extends Form if (!preg_match('/</', $listaliasval)) { $listaliasval = '<'.$listaliasval.'>'; } - $liste[$typealias.'_'.$posalias] = $listaliasval; + $liste[$typealias.'_'.$posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval); } } } @@ -1285,22 +1285,26 @@ class FormMail extends Form * @param string $type_template Get message for model/type=$type_template, type='all' also included. * @param User $user Get templates public + limited to this user * @param Translate $outputlangs Output lang object - * @param int $id Id of template to get, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found) + * @param int $id Id of template to get, or + * -1 for first found with position 0, or + * 0 for first found whatever is position (priority order depends on lang provided or not) or + * -2 for exact match with label (no answer if not found) * @param int $active 1=Only active template, 0=Only disabled, -1=All * @param string $label Label of template to get + * @param int $defaultfortype 1=Only default templates, 0=Only not default, -1=All * @return ModelMail|integer One instance of ModelMail or < 0 if error */ - public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') + public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '', $defaultfortype = -1) { - global $conf, $langs; - - $ret = new ModelMail(); + global $conf; if ($id == -2 && empty($label)) { - $this->error = 'LabelIsMandatoryWhenIdIs-2'; + $this->error = 'LabelIsMandatoryWhenIdIs-2or-3'; return -1; } + $ret = new ModelMail(); + $languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : ''); // Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX') $tmparray = explode('_', $languagetosearch); @@ -1317,6 +1321,9 @@ class FormMail extends Form if ($active >= 0) { $sql .= " AND active = ".((int) $active); } + if ($defaultfortype >= 0) { + $sql .= " AND defaultfortype = ".((int) $defaultfortype); + } if ($label) { $sql .= " AND label = '".$dbs->escape($label)."'"; } @@ -1457,11 +1464,11 @@ class FormMail extends Form * Find if template exists and are available for current user, then set them into $this->lines_module. * Search into table c_email_templates * - * @param string $type_template Get message for key module - * @param User $user Use template public or limited to this user - * @param Translate $outputlangs Output lang object - * @param int $active 1=Only active template, 0=Only disabled, -1=All - * @return int <0 if KO, nb of records found if OK + * @param string $type_template Get message for key module + * @param User $user Use template public or limited to this user + * @param Translate $outputlangs Output lang object + * @param int $active 1=Only active template, 0=Only disabled, -1=All + * @return int <0 if KO, nb of records found if OK */ public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1) { diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 118e75773c1..cce5cf7819d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -429,7 +429,9 @@ class FormOther if (!is_numeric($showempty)) { $textforempty = $showempty; } - $moreforfilter .= ''."\n"; + $moreforfilter .= ''; // Opp status @@ -1038,9 +1038,10 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl if (!empty($extrafields->attributes[$contactstatic->table_element]['list'][$key])) { $arrayfields["ef.".$key] = array( 'label'=>$extrafields->attributes[$contactstatic->table_element]['label'][$key], - 'checked'=>(($extrafields->attributes[$contactstatic->table_element]['list'][$key] < 0) ? 0 : 1), + 'checked'=>((dol_eval($extrafields->attributes[$contactstatic->table_element]['list'][$key], 1, 1, '1') < 0) ? 0 : 1), 'position'=>1000 + $extrafields->attributes[$contactstatic->table_element]['pos'][$key], - 'enabled'=>(abs($extrafields->attributes[$contactstatic->table_element]['list'][$key]) != 3 && $extrafields->attributes[$contactstatic->table_element]['perms'][$key])); + 'enabled' => (abs((int) dol_eval($extrafields->attributes[$contactstatic->table_element]['list'][$key], 1)) != 3 && dol_eval($extrafields->attributes[$contactstatic->table_element]['perms'][$key], 1, 1, '1')) + ); } } } @@ -1339,7 +1340,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl // Photo - Name if (!empty($arrayfields['t.name']['checked'])) { - print ''; @@ -1347,17 +1348,18 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl // Job position if (!empty($arrayfields['t.poste']['checked'])) { - print ''; } // Address - Phone - Email if (!empty($arrayfields['t.address']['checked'])) { - print ''; } @@ -1379,7 +1381,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl // Birthday if (!empty($arrayfields['t.birthday']['checked'])) { - print ''; } @@ -1390,7 +1392,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl } if ($showuserlogin) { - print ''; + print ''; } } else { $colspan = 1 + ($showuserlogin ? 1 : 0); @@ -1442,7 +1444,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl $colspan++; } } - print ''; + print ''; } print "\n
'.$langs->trans("Filter").'
'.$langs->trans("ThirdParty").''; -$filter = ''; print img_picto('', 'company', 'class="pictofixedwidth"'); -print $form->select_company($socid, 'socid', $filter, 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', ''); +print $form->select_company($socid, 'socid', '', 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', ''); print '
'.$langs->trans("User").''; diff --git a/htdocs/compta/facture/agenda.php b/htdocs/compta/facture/agenda.php index a452a8dd6aa..45f495c1723 100644 --- a/htdocs/compta/facture/agenda.php +++ b/htdocs/compta/facture/agenda.php @@ -230,7 +230,7 @@ if ($object->id > 0) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } // Try to know count of actioncomm from cache diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 58c7e35724d..afff624102b 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3205,7 +3205,8 @@ if ($action == 'create') { } else { print '
'.$langs->trans('Customer').''; - print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500'); + $filter = '((s.client:=:1,3) AND (s.status:=:1))'; + print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500'); // Option to reload page to retrieve customer informations. if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) { print ''."\n"; * - * @param string $page Url of page to call if confirmation is OK. Can contains parameters (param 'action' and 'confirm' will be reformated) - * @param string $title Title - * @param string $question Question - * @param string $action Action - * @param array|string $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) - * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', - * 'other', 'onecolumn' or 'hidden'... - * @param int|string $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 - * @param int|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx - * @param int|string $height Force height of box (0 = auto) - * @param int $width Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones. - * @param int $disableformtag 1=Disable form tag. Can be used if we are already inside a section. - * @param string $labelbuttonyes Label for Yes - * @param string $labelbuttonno Label for No - * @return string HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form + * @param string $page Url of page to call if confirmation is OK. Can contains parameters (param 'action' and 'confirm' will be reformated) + * @param string $title Title + * @param string $question Question + * @param string $action Action + * @param array|string $formquestion An array with complementary inputs to add into forms: array(array('label'=> ,'type'=> , 'size'=>, 'morecss'=>, 'moreattr'=>'autofocus' or 'style=...')) + * 'type' can be 'text', 'password', 'checkbox', 'radio', 'date', 'datetime', 'select', 'multiselect', 'morecss', + * 'other', 'onecolumn' or 'hidden'... + * @param int|string $selectedchoice '' or 'no', or 'yes' or '1', 1, '0' or 0 + * @param int|string $useajax 0=No, 1=Yes use Ajax to show the popup, 2=Yes and also submit page with &confirm=no if choice is No, 'xxx'=Yes and preoutput confirm box with div id=dialog-confirm-xxx + * @param int|string $height Force height of box (0 = auto) + * @param int $width Force width of box ('999' or '90%'). Ignored and forced to 90% on smartphones. + * @param int $disableformtag 1=Disable form tag. Can be used if we are already inside a section. + * @param string $labelbuttonyes Label for Yes + * @param string $labelbuttonno Label for No + * @return string HTML ajax code if a confirm ajax popup is required, Pure HTML code if it's an html form */ public function formconfirm($page, $title, $question, $action, $formquestion = '', $selectedchoice = '', $useajax = 0, $height = 0, $width = 500, $disableformtag = 0, $labelbuttonyes = 'Yes', $labelbuttonno = 'No') { @@ -6068,18 +6093,18 @@ class Form /** * Output html select to select thirdparty * - * @param string $page Page - * @param string $selected Id preselected - * @param string $htmlname Name of HTML select - * @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 - * @param string $textifnothirdparty Text to show if no thirdparty - * @return string HTML output or '' + * @param string $page Page + * @param string $selected Id preselected + * @param string $htmlname Name of HTML select + * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). 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 + * @param string $textifnothirdparty Text to show if no thirdparty + * @return string HTML output or '' */ public function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0, $excludeids = array(), $textifnothirdparty = '') { @@ -6254,13 +6279,13 @@ class Form /** * Load into the cache vat rates of a country * - * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") - * @return int Nb of loaded lines, 0 if already loaded, <0 if KO + * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") + * @return int Nb of loaded lines, 0 if already loaded, <0 if KO */ public function load_cache_vatrates($country_code) { // phpcs:enable - global $langs; + global $langs, $user; $num = count($this->cache_vatrates); if ($num > 0) { @@ -6311,7 +6336,16 @@ class Form return $num; } else { - $this->error = '' . $langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code) . ''; + $this->error = ''; + $this->error .= $langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code); + $reg = array(); + if (!empty($user) && $user->admin && preg_match('/\'(..)\'/', $country_code, $reg)) { + $langs->load("errors"); + $new_country_code = $reg[1]; + $country_id = dol_getIdFromCode($this->db, $new_country_code, 'c_pays', 'code', 'rowid'); + $this->error .= '
'.$langs->trans("ErrorFixThisHere", DOL_URL_ROOT.'/admin/dict.php?id=10'.($country_id > 0 ? '&countryidforinsert='.$country_id : '')); + } + $this->error .= '
'; return -1; } } else { @@ -7814,19 +7848,19 @@ class Form * Can use autocomplete with ajax after x key pressed or a full combo, depending on setup. * This is the generic method that will replace all specific existing methods. * - * @param string $objectdesc ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]] - * @param string $htmlname Name of HTML select component - * @param int $preselectedvalue Preselected value (ID of element) - * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) - * @param string $searchkey Search criteria - * @param string $placeholder Place holder - * @param string $morecss More CSS - * @param string $moreparams More params provided to ajax call - * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) - * @param int $disabled 1=Html component is disabled - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @return string Return HTML string - * @see selectForFormsList() select_thirdparty_list() + * @param string $objectdesc ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]] + * @param string $htmlname Name of HTML select component + * @param int $preselectedvalue Preselected value (ID of element) + * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...) + * @param string $searchkey Search criteria + * @param string $placeholder Place holder + * @param string $morecss More CSS + * @param string $moreparams More params provided to ajax call + * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification) + * @param int $disabled 1=Html component is disabled + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @return string Return HTML string + * @see selectForFormsList(), select_thirdparty_list() */ public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '') { @@ -8112,26 +8146,26 @@ class Form /** - * Return a HTML select string, built from an array of key+value. + * Return a HTML select string, built from an array of key+value. * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. * - * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect - * @param array $array Array like array(key => value) or array(key=>array('label'=>..., 'data-...'=>..., 'disabled'=>..., 'css'=>...)) - * @param string|string[] $id Preselected key or preselected keys for multiselect. Use 'ifone' to autoselect record if there is only one record. - * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (If 1: key is -1 and value is '' or ' ', If placeholder string: key is -1 and value is the string), <0 to add an empty value with key that is this value. - * @param int $key_in_label 1 to show key into label with format "[key] value" - * @param int $value_as_key 1 to use value as key - * @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 int $translate 1=Translate and encode value - * @param int $maxlen Length maximum for labels - * @param int $disabled Html select box is disabled - * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order - * @param string $morecss Add more class to css styles - * @param int $addjscombo Add js combo - * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set - * @param int $disablebademail 1=Check if a not valid email, 2=Check string '---', and if found into value, disable and colorize entry - * @param int $nohtmlescape No html escaping. - * @return string HTML select string. + * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect + * @param array $array Array like array(key => value) or array(key=>array('label'=>..., 'data-...'=>..., 'disabled'=>..., 'css'=>...)) + * @param string|string[] $id Preselected key or preselected keys for multiselect. Use 'ifone' to autoselect record if there is only one record. + * @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (If 1: key is -1 and value is '' or ' ', If placeholder string: key is -1 and value is the string), <0 to add an empty value with key that is this value. + * @param int $key_in_label 1 to show key into label with format "[key] value" + * @param int $value_as_key 1 to use value as key + * @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 int $translate 1=Translate and encode value + * @param int $maxlen Length maximum for labels + * @param int $disabled Html select box is disabled + * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order + * @param string $morecss Add more class to css styles + * @param int $addjscombo Add js combo + * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set + * @param int $disablebademail 1=Check if a not valid email, 2=Check string '---', and if found into value, disable and colorize entry + * @param int $nohtmlescape No html escaping. + * @return string HTML select string. * @see multiselectarray(), selectArrayAjax(), selectArrayFilter() */ public static function selectarray($htmlname, $array, $id = '', $show_empty = 0, $key_in_label = 0, $value_as_key = 0, $moreparam = '', $translate = 0, $maxlen = 0, $disabled = 0, $sort = '', $morecss = 'minwidth75', $addjscombo = 1, $moreparamonempty = '', $disablebademail = 0, $nohtmlescape = 0) @@ -8245,7 +8279,7 @@ class Form if (is_array($tmpvalue)) { foreach ($tmpvalue as $keyforvalue => $valueforvalue) { if (preg_match('/^data-/', $keyforvalue)) { - $out .= ' ' . $keyforvalue . '="' . $valueforvalue . '"'; + $out .= ' '.$keyforvalue.'="'.dol_escape_htmltag($valueforvalue).'"'; } } } @@ -8377,18 +8411,18 @@ class Form * Return a HTML select string, built from an array of key+value, but content returned into select is defined into $array parameter. * Note: Do not apply langs->trans function on returned content of Ajax service, content may be entity encoded twice. * - * @param string $htmlname Name of html select area - * @param array $array Array (key=>array('text'=>'A text', 'url'=>'An url'), ...) - * @param string $id Preselected key - * @param string $moreparam Add more parameters onto the select tag - * @param int $disableFiltering If set to 1, results are not filtered with searched string - * @param int $disabled Html select box is disabled - * @param int $minimumInputLength Minimum Input Length - * @param string $morecss Add more class to css styles - * @param int $callurlonselect If set to 1, some code is added so an url return by the ajax is called when value is selected. - * @param string $placeholder String to use as placeholder - * @param integer $acceptdelayedhtml 1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) - * @return string HTML select string + * @param string $htmlname Name of html select area + * @param array $array Array (key=>array('text'=>'A text', 'url'=>'An url'), ...) + * @param string $id Preselected key + * @param string $moreparam Add more parameters onto the select tag + * @param int $disableFiltering If set to 1, results are not filtered with searched string + * @param int $disabled Html select box is disabled + * @param int $minimumInputLength Minimum Input Length + * @param string $morecss Add more class to css styles + * @param int $callurlonselect If set to 1, some code is added so an url return by the ajax is called when value is selected. + * @param string $placeholder String to use as placeholder + * @param integer $acceptdelayedhtml 1 = caller is requesting to have html js content not returned but saved into global $delayedhtmlcontent (so caller can show it at end of page to avoid flash FOUC effect) + * @return string HTML select string * @see selectArrayAjax(), ajax_combobox() in ajax.lib.php */ public static function selectArrayFilter($htmlname, $array, $id = '', $moreparam = '', $disableFiltering = 0, $disabled = 0, $minimumInputLength = 1, $morecss = '', $callurlonselect = 0, $placeholder = '', $acceptdelayedhtml = 0) @@ -8401,7 +8435,7 @@ class Form return ''; } - $out = ''; + $out = ''; $formattedarrayresult = array(); diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index 2cc15a3dd42..e2c87ff15e8 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -51,7 +51,7 @@ class FormAdmin * @param string $htmlname Name of HTML select * @param int $showauto Show 'auto' choice * @param array $filter Array of keys to exclude in list (opposite of $onlykeys) - * @param string $showempty '1'=Add empty value or 'string to show' + * @param int|string $showempty '1'=Add empty value or 'string to show' * @param int $showwarning Show a warning if language is not complete * @param int $disabled Disable edit of select * @param string $morecss Add more css styles @@ -93,7 +93,11 @@ class FormAdmin $out .= '
'; - //$out.='
'; if (is_numeric($this->withsubstit)) { $out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage } else { $out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage } $out .= "
'; if ($obj->opp_status_code) { - print price($obj->opp_amount, 1, '', 1, -1, -1, ''); + print ''.price($obj->opp_amount, 1, '', 1, -1, -1, '').''; } print ''; + print ''; print $form->showphoto('contact', $contactstatic, 0, 0, 0, 'photorefnoborder valignmiddle marginrightonly', 'small', 1, 0, 1); print $contactstatic->getNomUrl(0, '', 0, '&backtopage='.urlencode($backtopage)); print ''; + print ''; if ($obj->poste) { - print $obj->poste; + print dol_escape_htmltag($obj->poste); } print ''; - print $contactstatic->getBannerAddress('contact', $object); + $addresstoshow = $contactstatic->getBannerAddress('contact', $object); + print ''; + print $addresstoshow; print ''; + print ''; print dol_print_date($db->jdate($obj->birthday)); print ''; + print ''; $tmpuser= new User($db); $resfetch = $tmpuser->fetch(0, '', '', 0, -1, '', $contactstatic->id); if ($resfetch > 0) { @@ -1433,7 +1435,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '', $showuserl $colspan++; } } - print '
'.$langs->trans("NoRecordFound").'
'.$langs->trans("NoRecordFound").'
'.$langs->trans("None").'
'.$langs->trans("None").'
\n"; print '
'; diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index 2dbf97d4785..e864060bc25 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -93,7 +93,7 @@ function contact_prepare_head(Contact $object) } // Related items - if (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || isModEnabled('ficheinter') || (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { + if (isModEnabled('commande') || isModEnabled("propal") || isModEnabled('facture') || isModEnabled('ficheinter') || isModEnabled("supplier_proposal") || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { $head[$tab][0] = DOL_URL_ROOT.'/contact/consumption.php?id='.$object->id; $head[$tab][1] = $langs->trans("Referers"); $head[$tab][2] = 'consumption'; diff --git a/htdocs/core/lib/expedition.lib.php b/htdocs/core/lib/expedition.lib.php index 21076122903..ea692fc2ab7 100644 --- a/htdocs/core/lib/expedition.lib.php +++ b/htdocs/core/lib/expedition.lib.php @@ -53,7 +53,7 @@ function expedition_prepare_head(Expedition $object) $hselected = $h; $h++; - if (!empty($conf->global->MAIN_SUBMODULE_DELIVERY)) { + if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { $head[$h][0] = DOL_URL_ROOT."/admin/delivery.php"; $head[$h][1] = $langs->trans("Receivings"); $h++; @@ -121,7 +121,7 @@ function expedition_admin_prepare_head() $head[$h][2] = 'receivings'; $h++; - if (!empty($conf->global->MAIN_SUBMODULE_DELIVERY)) { + if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { $extrafields->fetch_name_optionals_label('delivery'); $extrafields->fetch_name_optionals_label('deliverydet'); diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index d0c2d9998b4..8ad67df141d 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1808,10 +1808,16 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess $resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles, $upload_dir); if (is_numeric($resupload) && $resupload > 0) { // $resupload can be 'ErrorFileAlreadyExists' - global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini; - include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; + $tmparraysize = getDefaultImageSizes(); + $maxwidthsmall = $tmparraysize['maxwidthsmall']; + $maxheightsmall = $tmparraysize['maxheightsmall']; + $maxwidthmini = $tmparraysize['maxwidthmini']; + $maxheightmini = $tmparraysize['maxheightmini']; + //$quality = $tmparraysize['quality']; + $quality = 50; // For thumbs, we force quality to 50 + // Generate thumbs. if ($generatethumbs) { if (image_format_supported($destfull) == 1) { @@ -1819,10 +1825,10 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess // We can't use $object->addThumbs here because there is no $object known // Used on logon for example - $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); + $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', $quality, "thumbs"); // Create mini thumbs for image (Ratio is near 16/9) // Used on menu or for setup page for example - $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', $quality, "thumbs"); } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 2da236006c0..7bf81f84e2c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -20,6 +20,7 @@ * Copyright (C) 2022 Anthony Berton * Copyright (C) 2022 Ferran Marcet * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2023 Joachim Kueter * * 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 @@ -160,13 +161,28 @@ function getDolUserInt($key, $default = 0, $tmpuser = null) /** * Is Dolibarr module enabled * - * @param string $module module name to check - * @return int + * @param string $module Module name to check + * @return boolean True if module is enabled */ function isModEnabled($module) { global $conf; - return !empty($conf->$module->enabled); + + // Fix special cases + $arrayconv = array( + 'project' => 'projet', + 'contract' => 'contrat' + ); + if (empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) { + $arrayconv['supplier_order'] = 'fournisseur'; + $arrayconv['supplier_invoice'] = 'fournisseur'; + } + if (!empty($arrayconv[$module])) { + $module = $arrayconv[$module]; + } + + return !empty($conf->modules[$module]); + //return !empty($conf->$module->enabled); } /** @@ -232,7 +248,7 @@ function getEntity($element, $shared = 1, $currentobject = null) $out = $mc->getEntity($element, $shared, $currentobject); } else { $out = ''; - $addzero = array('user', 'usergroup', 'c_email_templates', 'email_template', 'default_values'); + $addzero = array('user', 'usergroup', 'cronjob', 'c_email_templates', 'email_template', 'default_values'); if (in_array($element, $addzero)) { $out .= '0,'; } @@ -619,7 +635,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null } } if (!empty($conf->global->MAIN_ENABLE_DEFAULT_VALUES)) { - if (!empty($_GET['action']) && (preg_match('/^create|^add_price|^make/', $_GET['action']) || preg_match('/^presend/', $_GET['action'])) && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) { + if (!empty($_GET['action']) && (preg_match('/^create/', $_GET['action']) || preg_match('/^presend/', $_GET['action'])) && !isset($_GET[$paramname]) && !isset($_POST[$paramname])) { // Now search in setup to overwrite default values if (!empty($user->default_values)) { // $user->default_values defined from menu 'Setup - Default values' if (isset($user->default_values[$relativepathstring]['createform'])) { @@ -1431,13 +1447,17 @@ function dol_string_unaccent($str) * @param string $newstr String to replace forbidden chars with * @param array|string $badcharstoreplace Array of forbidden characters to replace. Use '' to keep default list. * @param array|string $badcharstoremove Array of forbidden characters to remove. Use '' to keep default list. + * @param int $keepspaces 1=Do not treat space as a special char to replace or remove * @return string Cleaned string * * @see dol_sanitizeFilename(), dol_string_unaccent(), dol_string_nounprintableascii() */ -function dol_string_nospecial($str, $newstr = '_', $badcharstoreplace = '', $badcharstoremove = '') +function dol_string_nospecial($str, $newstr = '_', $badcharstoreplace = '', $badcharstoremove = '', $keepspaces = 0) { - $forbidden_chars_to_replace = array(" ", "'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ",", ";", "=", '°', '$', ';'); // more complete than dol_sanitizeFileName + $forbidden_chars_to_replace = array("'", "/", "\\", ":", "*", "?", "\"", "<", ">", "|", "[", "]", ",", ";", "=", '°', '$', ';'); // more complete than dol_sanitizeFileName + if (empty($keepspaces)) { + $forbidden_chars_to_replace[] = " "; + } $forbidden_chars_to_remove = array(); //$forbidden_chars_to_remove=array("(",")"); @@ -1521,7 +1541,7 @@ function dol_escape_json($stringtoescape) } /** - * Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields. + * Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input fields. * * @param string $stringtoescape String to escape * @param int $keepb 1=Keep b tags, 0=remove them completely @@ -1529,7 +1549,7 @@ function dol_escape_json($stringtoescape) * @param string $noescapetags '' or 'common' or list of tags to not escape. TODO Does not works yet when there is attributes into tag. * @param int $escapeonlyhtmltags 1=Escape only html tags, not the special chars like accents. * @return string Escaped string - * @see dol_string_nohtmltag(), dol_string_nospecial(), dol_string_unaccent() + * @see dol_string_nohtmltag(), dol_string_nospecial(), dol_string_unaccent(), dol_htmlentitiesbr() */ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapetags = '', $escapeonlyhtmltags = 0) { @@ -3569,7 +3589,7 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli } } - //if (($cid || $socid) && !empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) + //if (($cid || $socid) && isModEnabled('agenda') && $user->rights->agenda->myactions->create) if (isModEnabled('agenda') && $user->hasRight("agenda", "myactions", "create")) { $type = 'AC_TEL'; $link = ''; @@ -3786,22 +3806,22 @@ function dol_print_address($address, $htmlid, $element, $id, $noprint = 0, $char // TODO Remove this block, we can add this using the hook now $showgmap = $showomap = 0; - if (($element == 'thirdparty' || $element == 'societe') && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS)) { + if (($element == 'thirdparty' || $element == 'societe') && isModEnabled('google') && !empty($conf->global->GOOGLE_ENABLE_GMAPS)) { $showgmap = 1; } - if ($element == 'contact' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_CONTACTS)) { + if ($element == 'contact' && isModEnabled('google') && !empty($conf->global->GOOGLE_ENABLE_GMAPS_CONTACTS)) { $showgmap = 1; } - if ($element == 'member' && !empty($conf->google->enabled) && !empty($conf->global->GOOGLE_ENABLE_GMAPS_MEMBERS)) { + if ($element == 'member' && isModEnabled('google') && !empty($conf->global->GOOGLE_ENABLE_GMAPS_MEMBERS)) { $showgmap = 1; } - if (($element == 'thirdparty' || $element == 'societe') && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS)) { + if (($element == 'thirdparty' || $element == 'societe') && isModEnabled('openstreetmap') && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS)) { $showomap = 1; } - if ($element == 'contact' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_CONTACTS)) { + if ($element == 'contact' && isModEnabled('openstreetmap') && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_CONTACTS)) { $showomap = 1; } - if ($element == 'member' && !empty($conf->openstreetmap->enabled) && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_MEMBERS)) { + if ($element == 'member' && isModEnabled('openstreetmap') && !empty($conf->global->OPENSTREETMAP_ENABLE_MAPS_MEMBERS)) { $showomap = 1; } if ($showgmap) { @@ -5329,7 +5349,7 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin $options = '&'.$options; } - if (!$sortorder || $field1 != $sortfield1) { + if (!$sortorder || ($field1 != $sortfield1)) { //$out.= ''.img_down("A-Z",0).''; //$out.= ''.img_up("Z-A",0).''; } else { @@ -6204,7 +6224,7 @@ function isOnlyOneLocalTax($local) * Get values of localtaxes (1 or 2) for company country for the common vat with the highest value * * @param int $local LocalTax to get - * @return string Values of localtax (Can be '20', '-19:-15:-9') + * @return string Values of localtax (Can be '20', '-19:-15:-9') or 'Error' */ function get_localtax_by_third($local) { @@ -6221,12 +6241,14 @@ function get_localtax_by_third($local) $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - return $obj->localtax; - } else { - return 'Error'; + if ($obj) { + return $obj->localtax; + } else { + return '0'; + } } - return '0'; + return 'Error'; } @@ -7280,15 +7302,16 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = ' do { $oldstringtoclean = $out; + libxml_use_internal_errors(false); // Avoid to fill memory with xml errors + if (!empty($out) && !empty($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) && $check != 'restricthtmlallowunvalid') { try { $dom = new DOMDocument; // Add a trick to solve pb with text without parent tag - // like '

Foo

bar

' that wrongly ends up without the trick into '

Foo

bar

' - // like 'abc' that wrongly ends up without the tric into with '

abc

' + // like '

Foo

bar

' that wrongly ends up, without the trick, with '

Foo

bar

' + // like 'abc' that wrongly ends up, without the trick, with '

abc

' $out = '
'.$out.'
'; - - $dom->loadHTML($out, LIBXML_ERR_NONE|LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOXMLDECL); + $dom->loadHTML($out, LIBXML_HTML_NODEFDTD|LIBXML_ERR_NONE|LIBXML_HTML_NOIMPLIED|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOXMLDECL); $out = trim($dom->saveHTML()); // Remove the trick added to solve pb with text without parent tag @@ -8010,7 +8033,6 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, if ($object->fetch_optionals() > 0) { if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { - $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'__'] = $object->array_options['options_'.$key]; if ($extrafields->attributes[$object->table_element]['type'][$key] == 'date') { $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'__'] = dol_print_date($object->array_options['options_'.$key], 'day'); $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'_LOCALE__'] = dol_print_date($object->array_options['options_'.$key], 'day', 'tzserver', $outputlangs); @@ -8026,6 +8048,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, } elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'price') { $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'__'] = $object->array_options['options_'.$key]; $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'_FORMATED__'] = price($object->array_options['options_'.$key]); + } elseif ($extrafields->attributes[$object->table_element]['type'][$key] != 'separator') { + $substitutionarray['__EXTRAFIELD_'.strtoupper($key).'__'] = $object->array_options['options_'.$key]; } } } @@ -8040,6 +8064,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, // Set the online payment url link into __ONLINE_PAYMENT_URL__ key require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; $outputlangs->loadLangs(array('paypal', 'other')); + + $amounttouse = 0; $typeforonlinepayment = 'free'; if (is_object($object) && $object->element == 'commande') { $typeforonlinepayment = 'order'; @@ -8049,7 +8075,6 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, } if (is_object($object) && $object->element == 'member') { $typeforonlinepayment = 'member'; - $amounttouse = 0; if (!empty($object->last_subscription_amount)) { $amounttouse = $object->last_subscription_amount; } @@ -8522,21 +8547,28 @@ function dolGetFirstLastname($firstname, $lastname, $nameorder = -1) * * @param string|string[] $mesgs Message string or array * @param string $style Which style to use ('mesgs' by default, 'warnings', 'errors') + * @param int $noduplicate 1 means we do not add the message if already present in session stack * @return void * @see dol_htmloutput_events() */ -function setEventMessage($mesgs, $style = 'mesgs') +function setEventMessage($mesgs, $style = 'mesgs', $noduplicate = 0) { //dol_syslog(__FUNCTION__ . " is deprecated", LOG_WARNING); This is not deprecated, it is used by setEventMessages function if (!is_array($mesgs)) { // If mesgs is a string if ($mesgs) { + if (!empty($noduplicate) && isset($_SESSION['dol_events'][$style]) && in_array($mesgs, $_SESSION['dol_events'][$style])) { + return; + } $_SESSION['dol_events'][$style][] = $mesgs; } } else { // If mesgs is an array foreach ($mesgs as $mesg) { if ($mesg) { + if (!empty($noduplicate) && isset($_SESSION['dol_events'][$style]) && in_array($mesg, $_SESSION['dol_events'][$style])) { + return; + } $_SESSION['dol_events'][$style][] = $mesg; } } @@ -8551,13 +8583,14 @@ function setEventMessage($mesgs, $style = 'mesgs') * @param array|null $mesgs Message array * @param string $style Which style to use ('mesgs' by default, 'warnings', 'errors') * @param string $messagekey A key to be used to allow the feature "Never show this message again" + * @param int $noduplicate 1 means we do not add the message if already present in session stack * @return void * @see dol_htmloutput_events() */ -function setEventMessages($mesg, $mesgs, $style = 'mesgs', $messagekey = '') +function setEventMessages($mesg, $mesgs, $style = 'mesgs', $messagekey = '', $noduplicate = 0) { if (empty($mesg) && empty($mesgs)) { - dol_syslog("Try to add a message in stack with empty message", LOG_WARNING); + dol_syslog("Try to add a message in stack, but value to add is empty message", LOG_WARNING); } else { if ($messagekey) { // Complete message with a js link to set a cookie "DOLHIDEMESSAGE".$messagekey; @@ -8569,12 +8602,12 @@ function setEventMessages($mesg, $mesgs, $style = 'mesgs', $messagekey = '') dol_print_error('', 'Bad parameter style='.$style.' for setEventMessages'); } if (empty($mesgs)) { - setEventMessage($mesg, $style); + setEventMessage($mesg, $style, $noduplicate); } else { if (!empty($mesg) && !in_array($mesg, $mesgs)) { - setEventMessage($mesg, $style); // Add message string if not already into array + setEventMessage($mesg, $style, $noduplicate); // Add message string if not already into array } - setEventMessage($mesgs, $style); + setEventMessage($mesgs, $style, $noduplicate); } } } @@ -9755,7 +9788,7 @@ function printCommonFooter($zone = 'private') // Google Analytics // TODO Add a hook here - if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AN_ID)) { + if (isModEnabled('google') && !empty($conf->global->MAIN_GOOGLE_AN_ID)) { $tmptagarray = explode(',', $conf->global->MAIN_GOOGLE_AN_ID); foreach ($tmptagarray as $tmptag) { print "\n"; @@ -9804,13 +9837,21 @@ function printCommonFooter($zone = 'private') * For example: "A=1;B=2;C=2" is exploded into array('A'=>1,'B'=>2,'C'=>3) * * @param string $string String to explode - * @param string $delimiter Delimiter between each couple of data + * @param string $delimiter Delimiter between each couple of data. Example: ';' or '[\n;]+' or '(\n\r|\r|\n|;)' * @param string $kv Delimiter between key and value * @return array Array of data exploded */ function dolExplodeIntoArray($string, $delimiter = ';', $kv = '=') { - if ($a = explode($delimiter, $string)) { + if (preg_match('/^\[.*\]$/sm', $delimiter) || preg_match('/^\(.*\)$/sm', $delimiter)) { + // This is a regex string + $newdelimiter = $delimiter; + } else { + // This is a simple string + $newdelimiter = preg_quote($delimiter, '/'); + } + + if ($a = preg_split('/'.$newdelimiter.'/', $string)) { $ka = array(); foreach ($a as $s) { // each part if ($s) { @@ -9823,6 +9864,7 @@ function dolExplodeIntoArray($string, $delimiter = ';', $kv = '=') } return $ka; } + return array(); } @@ -9866,10 +9908,10 @@ function dol_getmypid() * like "keyword1 keyword2" = We want record field like keyword1 AND field like keyword2 * or like "keyword1|keyword2" = We want record field like keyword1 OR field like keyword2 * If param $mode is 1, can contains an operator <, > or = like "<10" or ">=100.5 < -1000" - * If param $mode is 2, can contains a list of int id separated by comma like "1,3,4" - * If param $mode is 3, can contains a list of string separated by comma like "a,b,c" - * @param integer $mode 0=value is list of keyword strings, 1=value is a numeric test (Example ">5.5 <10"), 2=value is a list of ID separated with comma (Example '1,3,4') - * 3=value is list of string separated with comma (Example 'text 1,text 2'), 4=value is a list of ID separated with comma (Example '2,7') to be used to search into a multiselect string '1,2,3,4' + * If param $mode is 2 or -2, can contains a list of int id separated by comma like "1,3,4" + * If param $mode is 3 or -3, can contains a list of string separated by comma like "a,b,c". + * @param integer $mode 0=value is list of keyword strings, 1=value is a numeric test (Example ">5.5 <10"), 2=value is a list of ID separated with comma (Example '1,3,4'), -2 is for exclude list, + * 3=value is list of string separated with comma (Example 'text 1,text 2'), -3 if for exclude list, 4=value is a list of ID separated with comma (Example '2,7') to be used to search into a multiselect string '1,2,3,4' * @param integer $nofirstand 1=Do not output the first 'AND' * @return string $res The statement to append to the SQL query * @see dolSqlDateFilter() @@ -9884,7 +9926,7 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $value = preg_replace('/\*/', '%', $value); // Replace * with % } if ($mode == 1) { - $value = preg_replace('/([!<>=]+)\s+([0-9'.preg_quote($langs->trans("DecimalSeparator"), '/').'\-])/', '\1\2', $value); // Clean string '< 10' into '<10' so we can the explode on space to get all tests to do + $value = preg_replace('/([!<>=]+)\s+([0-9'.preg_quote($langs->trans("DecimalSeparator"), '/').'\-])/', '\1\2', $value); // Clean string '< 10' into '<10' so we can then explode on space to get all tests to do } $value = preg_replace('/\s*\|\s*/', '|', $value); @@ -9895,16 +9937,15 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $fields = array($fields); } - $j = 0; - foreach ($crits as $crit) { + $i1 = 0; // count the nb of and criteria added (all fields / criterias) + foreach ($crits as $crit) { // Loop on each AND criteria $crit = trim($crit); - $i = 0; - $i2 = 0; + $i2 = 0; // count the nb of valid criteria added for this this first criteria $newres = ''; foreach ($fields as $field) { if ($mode == 1) { $tmpcrits = explode('|', $crit); - $i3 = 0; // count the nb of valid criteria added for this field + $i3 = 0; // count the nb of valid criteria added for this current field foreach ($tmpcrits as $tmpcrit) { if ($tmpcrit !== '0' && empty($tmpcrit)) { continue; @@ -9931,7 +9972,7 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $i3++; // a criteria was added to string } } - $i2++; + $i2++; // a criteria for 1 more field was added to string } elseif ($mode == 2 || $mode == -2) { $crit = preg_replace('/[^0-9,]/', '', $crit); // ID are always integer $newres .= ($i2 > 0 ? ' OR ' : '').$field." ".($mode == -2 ? 'NOT ' : ''); @@ -9939,7 +9980,7 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) if ($mode == -2) { $newres .= ' OR '.$field.' IS NULL'; } - $i2++; // a criteria was added to string + $i2++; // a criteria for 1 more field was added to string } elseif ($mode == 3 || $mode == -3) { $tmparray = explode(',', $crit); if (count($tmparray)) { @@ -9952,7 +9993,7 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) } } $newres .= ($i2 > 0 ? ' OR ' : '').$field." ".($mode == -3 ? 'NOT ' : '')."IN (".$db->sanitize($listofcodes, 1).")"; - $i2++; // a criteria was added to string + $i2++; // a criteria for 1 more field was added to string } if ($mode == -3) { $newres .= ' OR '.$field.' IS NULL'; @@ -9969,20 +10010,20 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $newres .= ' OR '.$field." LIKE '%,".$db->escape($val)."'"; $newres .= ' OR '.$field." LIKE '%,".$db->escape($val).",%'"; $newres .= ')'; - $i2++; + $i2++; // a criteria for 1 more field was added to string (we can add several citeria for the same field as it is a multiselect search criteria) } } } } else { // $mode=0 $tmpcrits = explode('|', $crit); - $i3 = 0; // count the nb of valid criteria added for this field - foreach ($tmpcrits as $tmpcrit) { + $i3 = 0; // count the nb of valid criteria added for the current couple criteria/field + foreach ($tmpcrits as $tmpcrit) { // loop on each OR criteria if ($tmpcrit !== '0' && empty($tmpcrit)) { continue; } $tmpcrit = trim($tmpcrit); - if ($tmpcrit == '^$') { // If we search empty, we must combined different fields with AND + if ($tmpcrit == '^$' || strpos($crit, '!') === 0) { // If we search empty, we must combined different OR fields with AND $newres .= (($i2 > 0 || $i3 > 0) ? ' AND ' : ''); } else { $newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : ''); @@ -10028,15 +10069,15 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $i3++; } - $i2++; // a criteria was added to string + + $i2++; // a criteria for 1 more field was added to string } - $i++; } if ($newres) { $res = $res.($res ? ' AND ' : '').($i2 > 1 ? '(' : '').$newres.($i2 > 1 ? ')' : ''); } - $j++; + $i1++; } $res = ($nofirstand ? "" : " AND ")."(".$res.")"; @@ -11247,6 +11288,9 @@ function getElementProperties($element_type) $classpath = 'comm/action/class'; $subelement = 'Actioncomm'; $module = 'agenda'; + } elseif ($element_type == 'cronjob') { + $classpath = 'cron/class'; + $module = 'cron'; } elseif ($element_type == 'adherent_type') { $classpath = 'adherents/class'; $classfile = 'adherent_type'; @@ -11311,10 +11355,25 @@ function getElementProperties($element_type) $classpath = 'contrat/class'; $module = 'contrat'; $subelement = 'contrat'; + } elseif ($element_type == 'mailing') { + $classpath = 'comm/mailing/class'; + $module = 'mailing'; + $classfile = 'mailing'; + $classname = 'Mailing'; + $subelement = ''; } elseif ($element_type == 'member') { $classpath = 'adherents/class'; $module = 'adherent'; $subelement = 'adherent'; + } elseif ($element_type == 'usergroup') { + $classpath = 'user/class'; + $module = 'user'; + } elseif ($element_type == 'mo') { + $classpath = 'mrp/class'; + $classfile = 'mo'; + $classname = 'Mo'; + $module = 'mrp'; + $subelement = ''; } elseif ($element_type == 'cabinetmed_cons') { $classpath = 'cabinetmed/class'; $module = 'cabinetmed'; @@ -11368,6 +11427,10 @@ function getElementProperties($element_type) $classname = 'Websitepage'; $module = 'website'; $subelement = 'websitepage'; + } elseif ($element_type == 'fiscalyear') { + $classpath = 'core/class'; + $module = 'accounting'; + $subelement = 'fiscalyear'; } if (empty($classfile)) { @@ -11722,11 +11785,14 @@ function jsonOrUnserialize($stringtodecode) /** * forgeSQLFromUniversalSearchCriteria * - * @param string $filter String with universal search string. Must be (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'. + * @param string $filter String with universal search string. Must be (aaa:bbb:...) with + * aaa is a field name (with alias or not) and + * bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'. * @param string $error Error message + * @param int $noand 0=Default, 1=Do not add the AND before the condition string. * @return string Return forged SQL string */ -function forgeSQLFromUniversalSearchCriteria($filter, &$error = '') +function forgeSQLFromUniversalSearchCriteria($filter, &$error = '', $noand = 0) { $regexstring = '\(([a-zA-Z0-9_\.]+:[<>!=insotlke]+:[^\(\)]+)\)'; // Must be (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot' @@ -11739,11 +11805,11 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$error = '') $t = str_replace(array('and','or','AND','OR',' '), '', $t); // Remove the only strings allowed between each () criteria // If the string result contains something else than '()', the syntax was wrong if (preg_match('/[^\(\)]/', $t)) { - $error = 'Bad syntax of the search string, filter criteria is inhalited'; + $error = 'Bad syntax of the search string, filter criteria is invalidated'; return 'Filter syntax error'; // Bad syntax of the search string, we force a SQL not found } - return " AND (".preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).")"; + return ($noand ? "" : " AND ")."(".preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).")"; } /** diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index ec64e77f42e..71e1d765de7 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -23,12 +23,34 @@ */ // Define size of logo small and mini +// TODO Remove this and call getDefaultImageSizes() instead $maxwidthsmall = 480; $maxheightsmall = 270; // Near 16/9eme $maxwidthmini = 128; $maxheightmini = 72; // 16/9eme $quality = 80; +/** + * Return default values for image sizes + * + * @return array Array of default values + */ +function getDefaultImageSizes() +{ + $maxwidthsmall = 480; + $maxheightsmall = 270; // Near 16/9eme + $maxwidthmini = 128; + $maxheightmini = 72; // 16/9eme + $quality = 80; + + return array( + 'maxwidthsmall' => $maxwidthsmall, + 'maxheightsmall' => $maxheightsmall, + 'maxwidthmini' => $maxwidthmini, + 'maxheightmini' => $maxheightmini, + 'quality' => $quality + ); +} /** * Return if a filename is file name of a supported image format diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 9c49035a757..cba7b3aa10d 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -56,7 +56,7 @@ function facture_prepare_head($object) $h++; } - if (!empty($conf->prelevement->enabled)) { + if (isModEnabled('prelevement')) { $nbStandingOrders = 0; $sql = "SELECT COUNT(pfd.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; @@ -1142,7 +1142,7 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $result = ''; - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled("supplier_invoice") && $user->rights->supplier_invoice->lire)) { + if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'read'))) { $facstatic = new FactureFournisseur($db); $sql = "SELECT ff.rowid, ff.ref, ff.fk_statut as status, ff.type, ff.libelle as label, ff.total_ht, ff.total_tva, ff.total_ttc, ff.paye"; diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index d5f2a6e50c8..83d06c43c55 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -742,3 +742,108 @@ function writePermsInAsciiDoc($file, $destfile) } return 1; } + +/** + * Add Object in ModuleApi File + * @param string $file path of file + * @param array $objects array of objects in the module + * @param string $modulename name of module + * @return int 1 if OK, -1 if KO + */ +function addObjectsToApiFile($file, $objects, $modulename) +{ + if (!file_exists($file)) { + return -1; + } + $content = file($file); + $includeClass = "dol_include_once('/mymodule/class/myobject.class.php');"; + $props = "public \$myobject;"; + $varcomented = "@var MyObject \$myobject {@type MyObject}"; + $constructObj = "\$this->myobject = new MyObject(\$this->db);"; + + // add properties and declare them in consturctor + foreach ($content as $lineNumber => &$lineContent) { + if (strpos($lineContent, $varcomented) !== false) { + $lineContent = ''; + foreach ($objects as $object) { + $lineContent .= "\t * @var ".$object." \$".strtolower($object)." {@type ".$object."}". PHP_EOL; + } + //var_dump($lineContent);exit; + } + if (strpos($lineContent, $props) !== false) { + $lineContent = ''; + foreach ($objects as $object) { + $lineContent .= "\tpublic \$".strtolower($object).";". PHP_EOL; + } + } + if (strpos($lineContent, $constructObj) !== false) { + $lineContent = ''; + foreach ($objects as $object) { + $lineContent .= "\t\t\$this->".strtolower($object)." = new ".$object."(\$this->db);". PHP_EOL; + } + } + if (strpos($lineContent, $includeClass) !== false) { + $lineContent = ''; + foreach ($objects as $object) { + $lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($object).".class.php');". PHP_EOL; + } + } + } + $allContent = implode("", $content); + file_put_contents($file, $allContent); + + //add methods for each object + $allContent = getFromFile($file, '/*begin methods CRUD*/', '/*end methods CRUD*/'); + foreach ($objects as $object) { + $contentReplaced =str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent); + dolReplaceInFile($file, array('/*end methods CRUD*/' => '/*CRUD FOR '.strtoupper($object).'*/'."\n".$contentReplaced."\n\t".'/*END CRUD FOR '.strtoupper($object).'*/'."\n\t".'/*end methods CRUD*/')); + } + dolReplaceInFile($file, array($allContent => '','MyModule' => ucfirst($modulename))); + return 1; +} + +/** + * Remove Object variables and methods from API_Module File + * @param string $file file api module + * @param string $objectname name of object whant to remove + * @param string $modulename name of module + * @return int 1 if OK, -1 if KO + */ +function removeObjectFromApiFile($file, $objectname, $modulename) +{ + $begin = '/*CRUD FOR '.strtoupper($objectname).'*/'; + $end = '/*END CRUD FOR '.strtoupper($objectname).'*/'; + $includeClass = "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');"; + $varcomentedDel = "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}"; + $propsDel = "\tpublic \$".strtolower($objectname).";"; + $constructObjDel = "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);"; + + if (!file_exists($file)) { + return -1; + } + $content = file($file); + // for delete property and the initialization from the construct + foreach ($content as $lineNumber => &$lineContent) { + if (strpos($lineContent, $includeClass) !== false) { + $lineContent = ''; + } + if (strpos($lineContent, $varcomentedDel) !== false) { + $lineContent = ''; + } + if (strpos($lineContent, $propsDel) !== false) { + $lineContent = ''; + } + if (strpos($lineContent, $constructObjDel) !== false) { + $lineContent = ''; + } + } + $allContent = implode("", $content); + file_put_contents($file, $allContent); + // for delete methods of object + $allContent = getFromFile($file, $begin, $end); + $check = dolReplaceInFile($file, array($allContent => '')); + if ($check) { + dolReplaceInFile($file, array($begin => '', $end => '')); + } + return 1; +} diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index cb5a2247953..8368df4496e 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -60,28 +60,28 @@ function commande_prepare_head(Commande $object) $h++; } - if ((isModEnabled('expedition_bon') && $user->hasRight('expedition', 'lire')) - || (isModEnabled('delivery_note') && $user->hasRight('expedition', 'delivery', 'lire'))) { + if ((getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && $user->hasRight('expedition', 'lire')) + || (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->hasRight('expedition', 'delivery', 'lire'))) { $nbShipments = $object->getNbOfShipments(); $nbReceiption = 0; $head[$h][0] = DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id; $text = ''; - if (isModEnabled('expedition_bon')) { + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION')) { $text .= $langs->trans("Shipments"); } - if (isModEnabled('expedition_bon') && isModEnabled('delivery_note')) { + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { $text .= ' - '; } - if (isModEnabled('delivery_note')) { + if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { $text .= $langs->trans("Receivings"); } if ($nbShipments > 0 || $nbReceiption > 0) { $text .= ''.($nbShipments ? $nbShipments : 0); } - if (isModEnabled('expedition_bon') && isModEnabled('delivery_note') && ($nbShipments > 0 || $nbReceiption > 0)) { + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && ($nbShipments > 0 || $nbReceiption > 0)) { $text .= ' - '; } - if (isModEnabled('expedition_bon') && isModEnabled('delivery_note') && ($nbShipments > 0 || $nbReceiption > 0)) { + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && ($nbShipments > 0 || $nbReceiption > 0)) { $text .= ($nbReceiption ? $nbReceiption : 0); } if ($nbShipments > 0 || $nbReceiption > 0) { diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 72903dd9e76..89e0936611f 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2008-2023 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 @@ -18,7 +18,7 @@ /** * \file htdocs/core/lib/parsemd.lib.php - * \brief This file contains functions dedicated to MD parsind. + * \brief This file contains functions dedicated to MD parsing. */ /** @@ -40,8 +40,9 @@ function dolMd2Html($content, $parser = 'parsedown', $replaceimagepath = null) } if ($parser == 'parsedown') { include_once DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; - $Parsedown = new Parsedown(); - $content = $Parsedown->text($content); + $parsedown = new Parsedown(); + $parsedown->setSafeMode(true); // This will escape HTML link into html entities but markdown links are ok + $content = $parsedown->text($content); } else { $content = nl2br($content); } diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php index ef89c65bdf1..e9859e79cb6 100644 --- a/htdocs/core/lib/payments.lib.php +++ b/htdocs/core/lib/payments.lib.php @@ -187,12 +187,12 @@ function getValidOnlinePaymentMethods($paymentmethod = '') /** * Return string with full online payment Url * - * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member' ...) - * @param string $ref Ref of object - * @param int $amount Amount of money to request for - * @return string Url string + * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member' ...) + * @param string $ref Ref of object + * @param int|float $amount Amount of money to request for + * @return string Url string */ -function showOnlinePaymentUrl($type, $ref, $amount = '9.99') +function showOnlinePaymentUrl($type, $ref, $amount = 0) { global $langs; @@ -213,13 +213,13 @@ function showOnlinePaymentUrl($type, $ref, $amount = '9.99') /** * Return string with HTML link for online payment * - * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member' ...) - * @param string $ref Ref of object - * @param string $label Text or HTML tag to display, if empty it display the URL - * @param int $amount Amount of money to request for - * @return string Url string + * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member' ...) + * @param string $ref Ref of object + * @param string $label Text or HTML tag to display, if empty it display the URL + * @param int|float $amount Amount of money to request for + * @return string Url string */ -function getHtmlOnlinePaymentLink($type, $ref, $label = '', $amount = '9.99') +function getHtmlOnlinePaymentLink($type, $ref, $label = '', $amount = 0) { $url = getOnlinePaymentUrl(0, $type, $ref, $amount); $label = $label ? $label : $url; @@ -230,15 +230,15 @@ function getHtmlOnlinePaymentLink($type, $ref, $label = '', $amount = '9.99') /** * Return string with full Url * - * @param int $mode 0=True url, 1=Url formated with colors - * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member', 'boothlocation', ...) - * @param string $ref Ref of object - * @param int $amount Amount of money to request for - * @param string $freetag Free tag (required and used for $type='free' only) - * @param string $localorexternal 0=Url for browser, 1=Url for external access - * @return string Url string + * @param int $mode 0=True url, 1=Url formated with colors + * @param string $type Type of URL ('free', 'order', 'invoice', 'contractline', 'member', 'boothlocation', ...) + * @param string $ref Ref of object + * @param int|float $amount Amount of money to request for + * @param string $freetag Free tag (required and used for $type='free' only) + * @param string $localorexternal 0=Url for browser, 1=Url for external access + * @return string Url string */ -function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_tag', $localorexternal = 1) +function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = 0, $freetag = 'your_tag', $localorexternal = 1) { global $conf, $dolibarr_main_url_root; diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 03e816a63f9..3b893e39256 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -603,10 +603,12 @@ function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $t } } else { if (is_object($targetcompany)) { - $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany))."\n"; + $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($targetcompany)); // Country if (!empty($targetcompany->country_code) && $targetcompany->country_code != $sourcecompany->country_code) { $stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($outputlangs->transnoentitiesnoconv("Country".$targetcompany->country_code)); + } else { + $stringaddress .= ($stringaddress ? "\n" : ''); } if (!empty($conf->global->MAIN_PDF_ADDALSOTARGETDETAILS) || preg_match('/targetwithdetails/', $mode)) { diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index ed3f8d7a4a3..408f661e2b9 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -70,7 +70,7 @@ function product_prepare_head($object) } if (!empty($object->status_buy) || (isModEnabled('margin') && !empty($object->status))) { // If margin is on and product on sell, we may need the cost price even if product os not on purchase - if ((((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $user->rights->fournisseur->lire) + if ((isModEnabled("supplier_proposal") || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && ($user->hasRight('fournisseur', 'lire') || $user->hasRight('supplier_order', 'read') || $user->hasRight('supplier_invoice', 'read')) || (isModEnabled('margin') && $user->hasRight("margin", "liretous")) ) { if ($usercancreadprice) { diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 9baccc8e9fc..dd7026a0d60 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -99,7 +99,7 @@ function project_prepare_head(Project $project, $moreparam = '') $nbTimeSpent = $dataretrieved; } else { $sql = "SELECT t.rowid"; - //$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; + //$sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; //$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt"; $sql .= " WHERE t.fk_element = pt.rowid"; @@ -126,7 +126,7 @@ function project_prepare_head(Project $project, $moreparam = '') $h++; } - if (((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) + if (isModEnabled("supplier_proposal") || isModEnabled("supplier_order") || isModEnabled("supplier_invoice") || isModEnabled("propal") || isModEnabled('commande') || isModEnabled('facture') || isModEnabled('contrat') || isModEnabled('ficheinter') || isModEnabled('agenda') || isModEnabled('deplacement') || isModEnabled('stock')) { @@ -372,7 +372,7 @@ function task_prepare_head($object) // Is there timespent ? $nbTimeSpent = 0; $sql = "SELECT t.rowid"; - //$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; + //$sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; //$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; $sql .= " WHERE t.elementtype='task' AND t.fk_element = ".((int) $object->id); @@ -1153,7 +1153,7 @@ function projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projec if (empty($workloadforid[$projectstatic->id])) { if ($preselectedday) { - $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id] = 1; } } @@ -1391,7 +1391,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr if (empty($workloadforid[$projectstatic->id])) { if ($preselectedday) { - $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id] = 1; } } @@ -1788,7 +1788,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ //var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]); //var_dump($projectstatic->weekWorkLoadPerTask); if (empty($workloadforid[$projectstatic->id])) { - $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id] = 1; } //var_dump($projectstatic->weekWorkLoadPerTask); @@ -2175,7 +2175,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & //var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]); //var_dump($projectstatic->weekWorkLoadPerTask); if (empty($workloadforid[$projectstatic->id])) { - $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id] = 1; } //var_dump($projectstatic->weekWorkLoadPerTask); @@ -2811,8 +2811,8 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide // this conf is actually hidden, by default we use 10% for "be carefull or warning" $warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.10; - $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); - $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); + $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.(isset($task->progress) ? '%' : ''); + $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.(isset($progressCalculated) ? '%' : ''); //var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.floatval($task->progress * $warningRatio)); if (floatval($progressCalculated) > floatval($task->progress * $warningRatio)) { diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php index 588418c7449..b24fec85a9c 100644 --- a/htdocs/core/lib/propal.lib.php +++ b/htdocs/core/lib/propal.lib.php @@ -42,16 +42,19 @@ function propal_prepare_head($object) $head[$h][2] = 'comm'; $h++; - if ((empty($conf->commande->enabled) && ((isModEnabled("expedition") && isModEnabled('expedition_bon') && $user->rights->expedition->lire) - || (isModEnabled("expedition") && !empty($conf->delivery_note->enabled) && $user->rights->expedition->delivery->lire)))) { + if ((empty($conf->commande->enabled) && ((isModEnabled("expedition") && getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && $user->rights->expedition->lire) + || (isModEnabled("expedition") && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->rights->expedition->delivery->lire)))) { $langs->load("sendings"); $text = ''; $head[$h][0] = DOL_URL_ROOT.'/expedition/propal.php?id='.$object->id; - if (isModEnabled('expedition_bon')) { + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION')) { $text = $langs->trans("Shipment"); } - if (isModEnabled('delivery_note')) { - $text .= '/'.$langs->trans("Receivings"); + if (getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { + $text .= '/'; + } + if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) { + $text .= $langs->trans("Receivings"); } $head[$h][1] = $text; $head[$h][2] = 'shipping'; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 3c9ca5e34d9..f75bb21eae9 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -109,6 +109,7 @@ function dolGetRandomBytes($length) /** * Encode a string with a symetric encryption. Used to encrypt sensitive data into database. * Note: If a backup is restored onto another instance with a different $dolibarr_main_instance_unique_id, then decoded value will differ. + * This function is called for example by dol_set_const() when saving a sensible data into database configuration table llx_const. * * @param string $chain string to encode * @param string $key If '', we use $dolibarr_main_instance_unique_id @@ -335,7 +336,7 @@ function dolGetLdapPasswordHash($password, $type = 'md5') * @param string $features Features to check (it must be module name or $object->element. Can be a 'or' check with 'levela|levelb'. * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) * This is used to check permission $user->rights->features->... - * @param int|string|object $object Object or Object ID or list of Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). + * @param int|string|Object $object Object or Object ID or list of Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. * This is used to check permission $user->rights->features->feature2... @@ -400,11 +401,11 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', if ($features == 'productbatch') { $features = 'produit'; } - if ($features == 'fournisseur') { // When vendor invoice and pruchase order are into module 'fournisseur' + if ($features == 'fournisseur') { // When vendor invoice and purchase order are into module 'fournisseur' $features = 'fournisseur'; - if ($object->element == 'invoice_supplier') { + if (is_object($object) && $object->element == 'invoice_supplier') { $feature2 = 'facture'; - } elseif ($object->element == 'order_supplier') { + } elseif (is_object($object) && $object->element == 'order_supplier') { $feature2 = 'commande'; } } @@ -508,6 +509,11 @@ function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', if ($subfeature == 'user' && $user->id == $objectid) { continue; // A user can always read its own card } + if ($subfeature == 'fiscalyear' && $user->hasRight('accounting', 'fiscalyear', 'write')) { + // only one right for fiscalyear + $tmpreadok = 1; + continue; + } if (!empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) { $tmpreadok = 0; } elseif (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) { @@ -983,6 +989,8 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl $checkonentitydone = 1; } + //var_dump($checkonentitydone); + if (!$checkonentitydone && !in_array($feature, $nocheck) && $objectid > 0) { // By default (case of $checkdefault), we check on object entity + link to third party on field $dbt_keyfield // If external user: Check permission for external users if ($user->socid > 0) { @@ -994,7 +1002,7 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")"; $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid); } elseif (isModEnabled("societe") && empty($user->rights->societe->client->voir)) { - // If internal user: Check permission for internal users that are restricted on their objects + // If internal user without permission to see all thirdparties: Check permission for internal users that are restricted on their objects if ($feature != 'ticket') { if (empty($dbt_keyfield)) { dol_print_error('', 'Param dbt_keyfield is required but not defined'); @@ -1016,7 +1024,7 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)"; } } elseif (isModEnabled('multicompany')) { - // If multicompany and internal users with all permissions, check user is in correct entity + // If multicompany, and user is an internal user with all permissions, check that object is in correct entity $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")"; diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index b60054b9701..f6d354d9431 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -572,19 +572,20 @@ function dolJSToSetRandomPassword($htmlname, $htmlnameofbutton = 'generate_token if (!empty($conf->use_javascript_ajax)) { print "\n".''; print '' . "\n"; $searchform .= ''; } + + // Key map shortcut + $searchform .= ''; } // Left column diff --git a/htdocs/margin/agentMargins.php b/htdocs/margin/agentMargins.php index e68576edd81..c209fb1f957 100644 --- a/htdocs/margin/agentMargins.php +++ b/htdocs/margin/agentMargins.php @@ -347,6 +347,12 @@ if ($result) { } // Show total margin + if (!isset($cumul_achat)) { + $cumul_achat = 0; + } + if (!isset($cumul_vente)) { + $cumul_vente = 0; + } $totalMargin = $cumul_vente - $cumul_achat; $marginRate = ($cumul_achat != 0) ? (100 * $totalMargin / $cumul_achat) : ''; diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index d6ace40ad16..2d574ae6653 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -110,7 +110,8 @@ if ($socid > 0) { if ($soc->client) { print ''.$langs->trans('ThirdPartyName').''; print ''; - print img_picto('', 'company').$form->select_company($socid, 'socid', '(client=1 OR client=3)', 1, 0, 0); + $filter = '(client:IN:1,3)'; + print img_picto('', 'company').$form->select_company($socid, 'socid', $filter, 1, 0, 0); print ''; $client = true; diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index a1e5220e07a..17fcc123a2b 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -233,8 +233,15 @@ if (!defined('NOREQUIREDB') && !defined('NOREQUIRESOC')) { // This is very problematic during a fiscal control. $conf->global->INVOICE_DISABLE_REPLACEMENT = 1; } - - if ($mysoc->localtax1_assuj || $mysoc->localtax2_assuj) { + if ($mysoc->country_code == 'GR' && !isset($conf->global->INVOICE_DISABLE_REPLACEMENT)) { + // The replacement invoice type is not allowed in Greece. + $conf->global->INVOICE_DISABLE_REPLACEMENT = 1; + } + if ($mysoc->country_code == 'GR' && !isset($conf->global->INVOICE_DISABLE_DEPOSIT)) { + // The deposit invoice type is not allowed in Greece. + $conf->global->INVOICE_DISABLE_DEPOSIT = 1; + } + if (($mysoc->localtax1_assuj || $mysoc->localtax2_assuj) && !isset($conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX)) { // For countries using the 2nd or 3rd tax, we disable input/edit of lines using the price including tax (because 2nb and 3rd tax not yet taken into account). // Work In Progress to support all taxes into unit price entry when MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES is set. $conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX = 1; diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 03483212860..ef929f15180 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -471,72 +471,10 @@ if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontac ); if (count($objects) > 1) { - $file = $destfile; - $content = file($file); - $props = "public \$myobject;"; - $varcomented = "@var MyObject \$myobject {@type MyObject}"; - $constructObj = "\$this->myobject = new MyObject(\$this->db);"; - // add properties and declare them in consturctor - foreach ($content as $lineNumber => &$lineContent) { - if (strpos($lineContent, $varcomented) !== false) { - $lineContent = ''; - foreach ($objects as $object) { - $lineContent .= "\t * @var ".$object." \$".strtolower($object)." {@type ".$object."}". PHP_EOL; - } - //var_dump($lineContent);exit; - } - if (strpos($lineContent, $props) !== false) { - $lineContent = ''; - foreach ($objects as $object) { - $lineContent .= "\tpublic \$".strtolower($object).";". PHP_EOL; - } - } - if (strpos($lineContent, $constructObj) !== false) { - $lineContent = ''; - foreach ($objects as $object) { - $lineContent .= "\t\t\$this->".strtolower($object)."= new ".$object."(\$this->db);". PHP_EOL; - } - } - } - $allContent = implode("", $content); - file_put_contents($destfile, $allContent); - } - if (count($objects) > 1) { - $search = "/*begin methods CRUD*/"; - // Open the file and read line by line - $handle = fopen($destfile, "r"); - $i = 1; - $lines = array(); - $props = " public \$myobject; "; - while (($line = fgets($handle)) !== false) { - //search line begin - if (strpos($line, $search) !== false) { - $start_line = $i; - - // Copy lines until the end on array - while (($line = fgets($handle)) !== false) { - if (strpos($line, "/*end methods CRUD*/") !== false) { - $end_line = $i; - break; - } - $lines[] = $line; - $i++; - } - break; - } - - $i++; - } - $allContent = implode("", $lines); - - foreach ($objects as $object) { - $contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent); - dolReplaceInFile($destfile, array('/*end methods CRUD*/' => '/*CRUD FOR '.strtoupper($object).'*/'."\n".$contentReplaced."\n\t".'/*END CRUD FOR '.strtoupper($object).'*/'."\n\t".'/*end methods CRUD*/')); - } - dolReplaceInFile($destfile, array($allContent => '')); - fclose($handle); + addObjectsToApiFile($destfile, $objects, $modulename); } else { dolReplaceInFile($destfile, $arrayreplacement); + dolReplaceInFile($destfile, array('/*begin methods CRUD*/' => '/*begin methods CRUD*/'."\n\t".'/*CRUD FOR '.strtoupper($objectname).'*/', '/*end methods CRUD*/' => '/*END CRUD FOR '.strtoupper($objectname).'*/'."\n\t".'/*end methods CRUD*/')); } if ($varnametoupdate) { @@ -938,17 +876,25 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) { $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml')); - // Get list of existing objects - $objects = dolGetListOfObjectClasses($destdir); - - // Now we delete the file if ($relativefilename) { $dirnametodelete = dirname($relativefilename); $filetodelete = $dirins.'/'.$relativefilename; $dirtodelete = $dirins.'/'.$dirnametodelete; - $result = dol_delete_file($filetodelete); + //check when we want delete api_file + if (strpos($relativefilename, 'api') !== false) { + $removeFile = removeObjectFromApiFile($file_api, $objectname, $module); + $var = getFromFile($file_api, '/*begin methods CRUD*/', '/*end methods CRUD*/'); + if (str_word_count($var) == 0) { + $result = dol_delete_file($filetodelete); + } + if ($removeFile) { + setEventMessages($langs->trans("ApiObjectDeleted"), null); + } + } else { + $result = dol_delete_file($filetodelete); + } if (!$result) { setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors'); } else { diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 0bcfa07c672..911b5eb127f 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -121,7 +121,7 @@ class MyObject extends CommonObject 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1), 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>'isModEnabled("societe")', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'isModEnabled("project")', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1, 'cssview'=>'wordbreak'), @@ -368,8 +368,7 @@ class MyObject extends CommonObject $result = $object->createCommon($user); if ($result < 0) { $error++; - $this->error = $object->error; - $this->errors = $object->errors; + $this->setErrorsFromObject($object); } if (!$error) { @@ -753,13 +752,14 @@ class MyObject extends CommonObject /** * getTooltipContentArray - * @param array $params params to construct tooltip data - * @since v18 - * @return array + * + * @param array $params Params to construct tooltip data + * @since v18 + * @return array */ public function getTooltipContentArray($params) { - global $conf, $langs, $user; + global $conf, $langs; $datas = []; @@ -850,7 +850,7 @@ class MyObject extends CommonObject if (empty($this->showphoto_on_popup)) { if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1); } } else { if ($withpicto) { @@ -872,7 +872,7 @@ class MyObject extends CommonObject $result .= ''; } else { - $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); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1); } } } @@ -959,7 +959,7 @@ class MyObject extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return the status + * Return the label of a given status * * @param int $status Id status * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto @@ -1055,8 +1055,7 @@ class MyObject extends CommonObject $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.((int) $this->id))); if (is_numeric($result)) { - $this->error = $objectline->error; - $this->errors = $objectline->errors; + $this->setErrorsFromObject($objectline); return $result; } else { $this->lines = $result; diff --git a/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php b/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php index 7ea4b553e71..ace98374461 100644 --- a/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php +++ b/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2023 Frédéric France * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software: you can redistribute it and/or modify @@ -101,8 +101,10 @@ class mymodulewidget1 extends ModeleBoxes $this->param = $param; - //$this->enabled = $conf->global->FEATURES_LEVEL > 0; // Condition when module is enabled or not - //$this->hidden = ! ($user->rights->mymodule->myobject->read); // Condition when module is visible by user (test on permission) + // Condition when module is enabled or not + // $this->enabled = getDolGlobalInt('MAIN_FEATURES_LEVEL') > 0; + // Condition when module is visible by user (test on permission) + // $this->hidden = !$user->hasRight('mymodule', 'myobject', 'read'); } /** diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 2788c78fc37..9a4d667173a 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -135,10 +135,12 @@ class modMyModule extends DolibarrModules // Dependencies // A condition to hide module $this->hidden = false; - // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...) + // List of module class names that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR')...) $this->depends = array(); - $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...) - $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...) + // List of module class names to disable if this one is disabled. Example: array('modModuleToDisable1', ...) + $this->requiredby = array(); + // List of module class names this module is in conflict with. Example: array('modModuleToDisable1', ...) + $this->conflictwith = array(); // The language file dedicated to your module $this->langfiles = array("mymodule@mymodule"); @@ -221,7 +223,7 @@ class modMyModule extends DolibarrModules // Name of columns with primary key (try to always name it 'rowid') 'tabrowid'=>array("rowid", "rowid", "rowid"), // Condition to show each dictionary - 'tabcond'=>array($conf->mymodule->enabled, $conf->mymodule->enabled, $conf->mymodule->enabled), + 'tabcond'=>array(isModEnabled('mymodule'), isModEnabled('mymodule'), isModEnabled('mymodule')), // Tooltip for every fields of dictionaries: DO NOT PUT AN EMPTY ARRAY 'tabhelp'=>array(array('code'=>$langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), array('code'=>$langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), ...), ); @@ -252,13 +254,13 @@ class modMyModule extends DolibarrModules // 'frequency' => 2, // 'unitfrequency' => 3600, // 'status' => 0, - // 'test' => '$conf->mymodule->enabled', + // 'test' => 'isModEnabled("mymodule")', // 'priority' => 50, // ), ); // Example: $this->cronjobs=array( - // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50), - // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50) + // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'isModEnabled("mymodule")', 'priority'=>50), + // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'isModEnabled("mymodule")', 'priority'=>50) // ); // Permissions provided by this module @@ -437,11 +439,11 @@ class modMyModule extends DolibarrModules // Create extrafields during init //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; //$extrafields = new ExtraFields($this->db); - //$result1=$extrafields->addExtraField('mymodule_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled'); - //$result2=$extrafields->addExtraField('mymodule_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled'); - //$result3=$extrafields->addExtraField('mymodule_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled'); - //$result4=$extrafields->addExtraField('mymodule_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled'); - //$result5=$extrafields->addExtraField('mymodule_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled'); + //$result1=$extrafields->addExtraField('mymodule_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', 'isModEnabled("mymodule")'); + //$result2=$extrafields->addExtraField('mymodule_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', 'isModEnabled("mymodule")'); + //$result3=$extrafields->addExtraField('mymodule_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', 'isModEnabled("mymodule")'); + //$result4=$extrafields->addExtraField('mymodule_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'mymodule@mymodule', 'isModEnabled("mymodule")'); + //$result5=$extrafields->addExtraField('mymodule_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', 'isModEnabled("mymodule")'); // Permissions $this->remove($options); diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index c51bc01376c..9420c83b8c0 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -90,7 +90,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - if (empty($conf->mymodule) || empty($conf->mymodule->enabled)) { + if (!isModEnabled('mymodule')) { return 0; // If module is not enabled, we do nothing } diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 3b7b1b13009..3c7cc5f9ec5 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -186,8 +186,8 @@ END MODULEBUILDER DRAFT MYOBJECT */ print '
'; -$NBMAX = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; -$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; +$NBMAX = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); +$max = getDolGlobalInt('MAIN_SIZE_SHORTLIST_LIMIT'); /* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT // Last modified myobject diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php index 189bfd6282b..81d8c93f240 100644 --- a/htdocs/modulebuilder/template/myobject_agenda.php +++ b/htdocs/modulebuilder/template/myobject_agenda.php @@ -211,7 +211,7 @@ if ($object->id > 0) { // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); // Project - if (!empty($conf->project->enabled)) { + if (isModEnabled('project')) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) { @@ -301,7 +301,7 @@ if ($object->id > 0) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } // Try to know count of actioncomm from cache diff --git a/htdocs/modulebuilder/template/myobject_contact.php b/htdocs/modulebuilder/template/myobject_contact.php index 9568201238c..4f384a006e5 100644 --- a/htdocs/modulebuilder/template/myobject_contact.php +++ b/htdocs/modulebuilder/template/myobject_contact.php @@ -175,8 +175,7 @@ if ($object->id) { // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); // Project - if (!empty($conf->project->enabled)) - { + if (isModEnabled('project')) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php index ff1756e2b15..7ffa467cdc0 100644 --- a/htdocs/modulebuilder/template/myobject_document.php +++ b/htdocs/modulebuilder/template/myobject_document.php @@ -193,8 +193,7 @@ $morehtmlref = '
'; // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); // Project - if (!empty($conf->project->enabled)) - { + if (isModEnabled('project')) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index a1fcce9092a..e16fe9647ea 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -305,7 +305,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { - $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; + $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOST('search_current_entity', 'int') ? 0 : 1)).")"; } else { $sql .= " WHERE 1 = 1"; } @@ -717,6 +717,7 @@ while ($i < $imaxinloop) { // Show here line of result $j = 0; print ''; + // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; @@ -741,9 +742,9 @@ while ($i < $imaxinloop) { } if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; } elseif ($key == 'ref') { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; } if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { @@ -856,7 +857,7 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $genallowed = $permissiontoread; $delallowed = $permissiontoadd; - print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); + print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } // End of page diff --git a/htdocs/modulebuilder/template/myobject_note.php b/htdocs/modulebuilder/template/myobject_note.php index 1f3bf7c9fd4..584a7ccd9e3 100644 --- a/htdocs/modulebuilder/template/myobject_note.php +++ b/htdocs/modulebuilder/template/myobject_note.php @@ -168,8 +168,7 @@ if ($id > 0 || !empty($ref)) { // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); // Project - if (!empty($conf->project->enabled)) - { + if (isModEnabled('project')) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; if ($permissiontoadd) diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index 2312f4bd636..594cd0e1ac4 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -345,10 +345,10 @@ class Mos extends DolibarrApi } if (empty($labelmovement)) { - throw new RestException(500, "Field inventorylabel not prodivded"); + throw new RestException(500, "Field inventorylabel not provided"); } if (empty($codemovement)) { - throw new RestException(500, "Field inventorycode not prodivded"); + throw new RestException(500, "Field inventorycode not provided"); } // Code for consume and produce... diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index c5b1b061e54..cf4cbdb2edb 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -98,9 +98,9 @@ class Mo extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>'1', 'noteditable'=>1), - 'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:(t.status:=:1)', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>'$conf->bom->enabled', 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth300', 'csslist'=>'nowraponall', 'picto'=>'bom'), + 'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:(t.status:=:1)', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>'$conf->bom->enabled', 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'bom'), 'mrptype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>34, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth150', 'csslist'=>'minwidth150 center'), - 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:0', 'label'=>'Product', 'enabled'=>'$conf->product->enabled', 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'comment'=>"Product to produce", 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax100', 'picto'=>'product'), + 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:0', 'label'=>'Product', 'enabled'=>'isModEnabled("product")', 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'comment'=>"Product to produce", 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax100', 'picto'=>'product'), 'qty' => array('type'=>'real', 'label'=>'QtyToProduce', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>1, 'comment'=>"Qty to produce", 'css'=>'width75', 'default'=>1, 'isameasure'=>1), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>42, 'notnull'=>-1, 'searchall'=>1, 'showoncombobox'=>'2', 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200', 'alwayseditable'=>1), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'css'=>'maxwidth400', 'csslist'=>'tdoverflowmax150'), @@ -283,26 +283,23 @@ class Mo extends CommonObject */ public function create(User $user, $notrigger = false) { - global $conf; - $error = 0; $idcreated = 0; - $this->db->begin(); - - // Check that product is not a kit/virtual product - if (empty($conf->global->ALLOW_USE_KITS_INTO_BOM_AND_MO) && $this->fk_product > 0) { + // If kits feature is enabled and we don't allow kits into BOM and MO, we check that the product is not a kit/virtual product + if (getDolGlobalString('PRODUIT_SOUSPRODUITS') && !getDolGlobalString('ALLOW_USE_KITS_INTO_BOM_AND_MO') && $this->fk_product > 0) { include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $tmpproduct = new Product($this->db); $tmpproduct->fetch($this->fk_product); if ($tmpproduct->hasFatherOrChild(1) > 0) { $this->error = 'ErrorAVirtualProductCantBeUsedIntoABomOrMo'; $this->errors[] = $this->error; - $this->db->rollback(); return -1; } } + $this->db->begin(); + if ($this->fk_bom > 0) { // If there is a nown BOM, we force the type of MO to the type of BOM include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; @@ -320,7 +317,7 @@ class Mo extends CommonObject } if (!$error) { - $result = $this->updateProduction($user, $notrigger); // Insert lines from BOM + $result = $this->createProduction($user, $notrigger); // Insert lines from BOM if ($result <= 0) { $error++; } @@ -640,6 +637,7 @@ class Mo extends CommonObject $error++; } + // Update the lines (the qty) to consume or to produce $result = $this->updateProduction($user, $notrigger); if ($result <= 0) { $error++; @@ -654,6 +652,7 @@ class Mo extends CommonObject } } + /** * Erase and update the line to consume and to produce. * @@ -661,23 +660,19 @@ class Mo extends CommonObject * @param bool $notrigger false=launch triggers after, true=disable triggers * @return int <0 if KO, >0 if OK */ - public function updateProduction(User $user, $notrigger = true) + public function createProduction(User $user, $notrigger = true) { $error = 0; $role = ""; if ($this->status != self::STATUS_DRAFT) { - //$this->error = 'BadStatusForUpdateProduction'; - //return -1; - return 1; + return -1; } $this->db->begin(); // Insert lines in mrp_production table from BOM data if (!$error) { - // TODO Check that production has not started. If yes, we stop here. - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'mrp_production WHERE fk_mo = '.((int) $this->id); $this->db->query($sql); @@ -766,6 +761,53 @@ class Mo extends CommonObject } } + /** + * Update quantities in lines to consume and to produce. + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function updateProduction(User $user, $notrigger = true) + { + $error = 0; + + if ($this->status != self::STATUS_DRAFT) return 1; + + $this->db->begin(); + + $oldQty = $this->oldQty; + $newQty = $this->qty; + if ($newQty != $oldQty && !empty($this->oldQty)) { + $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "mrp_production WHERE fk_mo = " . (int) $this->id; + $resql = $this->db->query($sql); + if ($resql) { + while ($obj = $this->db->fetch_object($resql)) { + $moLine = new MoLine($this->db); + $res = $moLine->fetch($obj->rowid); + if (!$res) $error++; + + if ($moLine->role == 'toconsume' || $moLine->role == 'toproduce') { + if (empty($moLine->qty_frozen)) { + $qty = $newQty * $moLine->qty / $oldQty; + $moLine->qty = price2num($qty * (!empty($line->efficiency) ? $line->efficiency : 1 ), 'MS'); // Calculate with Qty to produce and more presition + $res = $moLine->update($user); + if (!$res) $error++; + } + } + } + } + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + /** * Delete object in database @@ -1220,7 +1262,7 @@ class Mo extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; @@ -1720,6 +1762,7 @@ class MoLine extends CommonObjectLine 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>170), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>-1, 'position'=>175), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'fk_default_workstation' =>array('type'=>'integer', 'label'=>'DefaultWorkstation', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>185) ); public $rowid; @@ -1744,6 +1787,11 @@ class MoLine extends CommonObjectLine public $import_key; public $fk_parent_line; + /** + * @var int Service Workstation + */ + public $fk_default_workstation; + /** * Constructor * diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index 470d87b727e..1ec339ee333 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -234,7 +234,7 @@ if ($object->id > 0) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index dd9cc457a72..675c3363576 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -123,6 +123,8 @@ if (empty($reshook)) { $backurlforlist = dol_buildpath('/mrp/mo_list.php', 1); + $object->oldQty = $object->qty; + if (empty($backtopage) || ($cancel && empty($id))) { if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php index d1d50441ea2..c49b5903046 100644 --- a/htdocs/mrp/mo_list.php +++ b/htdocs/mrp/mo_list.php @@ -379,7 +379,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index c450baf92fe..ae3ed6d9e34 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -513,7 +513,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($id > 0) { $param .= '&id='.urlencode($id); diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 8d3d11d167d..7bb0fb780aa 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -1,6 +1,7 @@ -/* Copyright (C) 2023 Christian Humpel + * Copyright (C) 2023 Christian Humpel + * Copyright (C) 2023 Vincent de Grandpré * * 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 @@ -168,6 +169,16 @@ if (empty($reshook)) { $moline->origin_type = 'free'; // free consume line $moline->position = 0; + // Is it a product or a service ? + if (!empty($moline->fk_product)) { + $tmpproduct = new Product($db); + $tmpproduct->fetch($moline->fk_product); + if ($tmpproduct->type == Product::TYPE_SERVICE) { + $moline->fk_default_workstation = $tmpproduct->fk_default_workstation; + } + $moline->disable_stock_change = ($tmpproduct->type == Product::TYPE_SERVICE ? 1 : 0); + } + $resultline = $moline->create($user, false); // Never use triggers here if ($resultline <= 0) { $error++; @@ -177,6 +188,7 @@ if (empty($reshook)) { $action = ''; // Redirect to refresh the tab information header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; } if (in_array($action, array('confirm_consumeorproduce', 'confirm_consumeandproduceall')) && $permissiontoproduce) { @@ -442,6 +454,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $res = $object->fetch_thirdparty(); $res = $object->fetch_optionals(); + if (!empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) && $object->fk_warehouse > 0) { + $tmpwarehouse->fetch($object->fk_warehouse); + $fk_default_warehouse = $object->fk_warehouse; + } + $head = moPrepareHead($object); print dol_get_fiche_head($head, 'production', $langs->trans("ManufacturingOrder"), -1, $object->picto); @@ -924,6 +941,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; // Warehouse print ''; + if (!empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) && $tmpwarehouse->id > 0) { + print img_picto('', $tmpwarehouse->picto)." ".$tmpwarehouse->label; + } print ''; // Stock if (isModEnabled('stock')) { @@ -932,7 +952,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!$line->disable_stock_change && $tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) { print img_warning($langs->trans('StockTooLow')) . ' '; } - print price2num($tmpproduct->stock_reel, 'MS'); // Available + if (empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) || empty($tmpwarehouse->id)) { + print price2num($tmpproduct->stock_reel, 'MS'); // Available + } else { + // Print only the stock in the selected warehouse + $tmpproduct->load_stock(); + $wh_stock = $tmpproduct->stock_warehouse[$tmpwarehouse->id]; + if (!empty($wh_stock)) { + print price2num($wh_stock->real, 'MS'); + } else { + print "0"; + } + } } print ''; } @@ -1123,6 +1154,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea }); '; + if (in_array($action, array('consumeorproduce', 'consumeandproduceall')) && + !empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE)) { + print ''; + } // Lines to produce diff --git a/htdocs/multicurrency/class/api_multicurrencies.class.php b/htdocs/multicurrency/class/api_multicurrencies.class.php index e88f936c571..7c9357a5f9b 100644 --- a/htdocs/multicurrency/class/api_multicurrencies.class.php +++ b/htdocs/multicurrency/class/api_multicurrencies.class.php @@ -28,29 +28,32 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/multicurrency.lib.php'; */ class MultiCurrencies extends DolibarrApi { - /** * Constructor */ public function __construct() { - global $db, $conf; + global $db; + $this->db = $db; } /** - * Get a list of currencies + * List Currencies * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.product_id:=:1) and (t.date_creation:<:'20160101')" - * @return array Array of warehouse objects + * Get a list of Currencies + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.product_id:=:1) and (t.date_creation:<:'20160101')" + * @return array Array of warehouse objects * * @throws RestException */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $sqlfilters = '') + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $sqlfilters = '') { - global $db, $conf; + global $db; $obj_ret = array(); @@ -100,12 +103,238 @@ class MultiCurrencies extends DolibarrApi return $obj_ret; } + /** + * Get properties of a Currency object + * + * Return an array with Currency informations + * + * @param int $id ID of Currency + * @return array|mixed Data without useless information + * + * @throws RestException + */ + public function get($id) + { + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch($id)) { + throw new RestException(404, 'Currency not found'); + } + + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->read) { + throw new RestException(401, "Insufficient rights to read currency"); + } + + return $this->_cleanObjectDatas($multicurrency); + } + + /** + * Get properties of a Currency object by code + * + * Return an array with Currency informations + * @url GET /bycode/{code} + * + * @param string $code Code of Currency (ex: EUR) + * @return array|mixed Data without useless information + * + * @throws RestException + */ + public function getByCode($code) + { + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch('', $code)) { + throw new RestException(404, 'Currency not found'); + } + + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->read) { + throw new RestException(401, "Insufficient rights to read currency"); + } + + return $this->_cleanObjectDatas($multicurrency); + } + + /** + * List Currency rates + * + * Get a list of Currency rates + * + * @url GET {id}/rates + * @param int $id ID of Currency + * @return array|mixed Data without useless information + * + * @throws RestException + */ + public function getRates($id) + { + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch($id)) { + throw new RestException(404, 'Currency not found'); + } + + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->read) { + throw new RestException(401, "Insufficient rights to read currency rates"); + } + + if ($multicurrency->fetchAllCurrencyRate() < 0) { + throw new RestException(500, "Error when fetching currency rates"); + } + + // Clean object datas + foreach ($multicurrency->rates as $key => $obj) { + $multicurrency->rates[$key] = $this->_cleanObjectDatasRate($obj); + } + + return $multicurrency->rates; + } + + /** + * Create Currency object + * + * @param array $request_data Request data + * @return int ID of Currency + * + * @throws RestException + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->create) { + throw new RestException(401, "Insufficient rights to create currency"); + } + + // Check parameters + if (!isset($request_data['code'])) { + throw new RestException(400, "code field missing"); + } + if (!isset($request_data['name'])) { + throw new RestException(400, "name field missing"); + } + + $multicurrency = new MultiCurrency($this->db); + $multicurrency->code = $request_data['code']; + $multicurrency->name = $request_data['name']; + + // Create Currency + if ($multicurrency->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating currency", array_merge(array($multicurrency->error), $multicurrency->errors)); + } + + // Add default rate if defined + if (isset($request_data['rate']) && $request_data['rate'] > 0) { + if ($multicurrency->addRate(DolibarrApiAccess::$user, $request_data['rate']) < 0) { + throw new RestException(500, "Error adding currency rate", array_merge(array($multicurrency->error), $multicurrency->errors)); + } + + return $multicurrency->id; + } + + return $multicurrency->id; + } + + /** + * Update Currency + * + * @param int $id Id of Currency to update + * @param array $request_data Datas + * @return array The updated Currency + * + * @throws RestException + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->create) { + throw new RestException(401, "Insufficient rights to update currency"); + } + + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch($id)) { + throw new RestException(404, 'Currency not found'); + } + + foreach ($request_data as $field => $value) { + if ($field == 'id') { + continue; + } + $multicurrency->$field = $value; + } + + if ($multicurrency->update(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error updating currency", array_merge(array($multicurrency->error), $multicurrency->errors)); + } + + return $this->get($id); + } + + /** + * Delete Currency + * + * @param int $id Currency ID + * @return array + * + * @throws RestException + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->delete) { + throw new RestException(401, "Insufficient rights to delete currency"); + } + + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch($id)) { + throw new RestException(404, 'Currency not found'); + } + + if (!$multicurrency->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, "Error deleting currency", array_merge(array($multicurrency->error), $multicurrency->errors)); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Currency deleted' + ) + ); + } + + + /** + * Update Currency rate + * @url PUT {id}/rates + * + * @param int $id Currency ID + * @param array $request_data Request data + * @return array The currency with the new rate + * + * @throws RestException + */ + public function updateRate($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->multicurrency->currency->create) { + throw new RestException(401, "Insufficient rights to update currency rate"); + } + + // Check parameters + if (!isset($request_data['rate'])) { + throw new RestException(400, "rate field missing"); + } + + $multicurrency = new MultiCurrency($this->db); + if (!$multicurrency->fetch($id)) { + throw new RestException(404, 'Currency not found'); + } + + // Add rate + if ($multicurrency->addRate($request_data['rate']) < 0) { + throw new RestException(500, "Error updating currency rate", array_merge(array($multicurrency->error), $multicurrency->errors)); + } + + return $this->_cleanObjectDatas($multicurrency); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Clean sensible object datas * - * @param MultiCurrency $object Object to clean - * @return Object Object with cleaned properties + * @param MultiCurrency $object Object to clean + * @return Object Object with cleaned properties */ protected function _cleanObjectDatas($object) { @@ -114,8 +343,30 @@ class MultiCurrencies extends DolibarrApi // Clear all fields out of interrest foreach ($object as $key => $value) { - if ($key == "rate") $object->$key = $this->_cleanObjectDatas($object->$key); - if ($key == "id" || $key == "code" || $key == "rate" || $key == "date_sync") + if ($key == "rate") $object->$key = $this->_cleanObjectDatasRate($object->$key); + if ($key == "id" || $key == "code" || $key == "rate" || $key == "name") + continue; + unset($object->$key); + } + + return $object; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Clean sensible MultiCurrencyRate object datas + * + * @param MultiCurrency $object Object to clean + * @return Object Object with cleaned properties + */ + protected function _cleanObjectDatasRate($object) + { + // phpcs:enable + $object = parent::_cleanObjectDatas($object); + + // Clear all fields out of interrest + foreach ($object as $key => $value) { + if ($key == "id" || $key == "rate" || $key == "date_sync") continue; unset($object->$key); } diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index da1b9f653b3..ad293b771db 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -299,7 +299,7 @@ class MultiCurrency extends CommonObject // Update request $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql .= " name = '".$this->db->escape($this->name)."'"; + $sql .= " name = '".$this->db->escape($this->name)."',"; $sql .= " code = '".$this->db->escape($this->code)."'"; $sql .= " WHERE rowid = ".((int) $this->id); diff --git a/htdocs/multicurrency/multicurrency_rate.php b/htdocs/multicurrency/multicurrency_rate.php index 8b9bbf4eef6..b518a0d378c 100644 --- a/htdocs/multicurrency/multicurrency_rate.php +++ b/htdocs/multicurrency/multicurrency_rate.php @@ -354,7 +354,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($sall) { $param .= "&sall=".urlencode($sall); diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index 770f16b07d2..18213acdb89 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -666,8 +666,8 @@ class Opensurveysondage extends CommonObject /** * Return status label of Order * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Libelle + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label if status */ public function getLibStatut($mode) { @@ -678,9 +678,9 @@ class Opensurveysondage extends CommonObject /** * Return label of status * - * @param int $status Id statut - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function LibStatut($status, $mode) { diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 5700909cd91..d845ef337d4 100644 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -243,7 +243,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } $fieldtosortuser = empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION) ? 'firstname' : 'lastname'; diff --git a/htdocs/partnership/partnership_agenda.php b/htdocs/partnership/partnership_agenda.php index 8214e3e907d..f4b8275a8f6 100644 --- a/htdocs/partnership/partnership_agenda.php +++ b/htdocs/partnership/partnership_agenda.php @@ -243,7 +243,7 @@ if ($object->id > 0) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } diff --git a/htdocs/partnership/partnership_list.php b/htdocs/partnership/partnership_list.php index 7259ae0ff2b..33b940748bd 100644 --- a/htdocs/partnership/partnership_list.php +++ b/htdocs/partnership/partnership_list.php @@ -587,7 +587,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($socid) { $param .= '&socid='.urlencode($socid); diff --git a/htdocs/paypal/admin/paypal.php b/htdocs/paypal/admin/paypal.php index 68759eeb5e3..bf71f80b1c6 100644 --- a/htdocs/paypal/admin/paypal.php +++ b/htdocs/paypal/admin/paypal.php @@ -176,7 +176,7 @@ print "\n"; print ''; print ''; print $langs->trans("PaypalLiveEnabled").''; -if (empty($conf->global->PAYPAL_API_SANDBOX)) { +if (!(getDolGlobalInt('PAYPAL_API_SANDBOX'))) { print '
'; print img_picto($langs->trans("Activated"), 'switch_on'); } else { @@ -187,27 +187,27 @@ print ''; print ''; print $langs->trans("PAYPAL_API_USER").''; -print ''; +print ''; print '   '.$langs->trans("Example").': admin-facilitator_api1.example.com, paypal_api1.mywebsite.com'; print ''; print ''; print $langs->trans("PAYPAL_API_PASSWORD").''; -print ''; +print ''; print ''; print ''; print $langs->trans("PAYPAL_API_SIGNATURE").''; -print ''; +print ''; print '
'.$langs->trans("Example").': ASsqXEmw4KzmX-CPChWSVDNCNfd.A3YNR7uz-VncXXAERFDFDFDF'; print ''; print ''; print $langs->trans("PAYPAL_SSLVERSION").''; -print $form->selectarray("PAYPAL_SSLVERSION", array('1'=> $langs->trans('TLSv1'), '6'=> $langs->trans('TLSv1.2')), $conf->global->PAYPAL_SSLVERSION); +print $form->selectarray("PAYPAL_SSLVERSION", array('1'=> $langs->trans('TLSv1'), '6'=> $langs->trans('TLSv1.2')), getDolGlobalString('PAYPAL_SSLVERSION')); print ''; print ''; @@ -228,7 +228,7 @@ print "\n"; print ''; print $langs->trans("PAYPAL_API_INTEGRAL_OR_PAYPALONLY").''; -print $form->selectarray("PAYPAL_API_INTEGRAL_OR_PAYPALONLY", array('integral'=> $langs->trans('PaypalModeIntegral'), 'paypalonly'=> $langs->trans('PaypalModeOnlyPaypal')), $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY); +print $form->selectarray("PAYPAL_API_INTEGRAL_OR_PAYPALONLY", array('integral'=> $langs->trans('PaypalModeIntegral'), 'paypalonly'=> $langs->trans('PaypalModeOnlyPaypal')), getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY')); print ''; /* @@ -241,7 +241,7 @@ print ''; print ''; print $langs->trans("PublicVendorName").''; -print ''; +print ''; print '   '.$langs->trans("Example").': '.$mysoc->name.''; print ''; @@ -249,47 +249,47 @@ if (isModEnabled("banque")) { print ''; print $langs->trans("BankAccount").''; print img_picto('', 'bank_account').' '; - $form->select_comptes($conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS, 'PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); + $form->select_comptes(getDolGlobalString('PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS'), 'PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); print ''; } print ''; print $langs->trans("CSSUrlForPaymentForm").''; -print ''; +print ''; print '   '.$langs->trans("Example").': http://mysite/mycss.css'; print ''; print ''; print $langs->trans("PAYPAL_ADD_PAYMENT_URL").''; -print $form->selectyesno("PAYPAL_ADD_PAYMENT_URL", $conf->global->PAYPAL_ADD_PAYMENT_URL, 1); +print $form->selectyesno("PAYPAL_ADD_PAYMENT_URL", getDolGlobalString('PAYPAL_ADD_PAYMENT_URL'), 1); print ''; print ''; print $langs->trans("MessageForm").''; -$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_FORM', $conf->global->ONLINE_PAYMENT_MESSAGE_FORM, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); +$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_FORM', getDolGlobalString('ONLINE_PAYMENT_MESSAGE_FORM'), '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); print ''; print ''; print $langs->trans("MessageOK").''; -$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_OK', $conf->global->ONLINE_PAYMENT_MESSAGE_OK, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); +$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_OK', getDolGlobalString('ONLINE_PAYMENT_MESSAGE_OK'), '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); print ''; print ''; print $langs->trans("MessageKO").''; -$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_KO', $conf->global->ONLINE_PAYMENT_MESSAGE_KO, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); +$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_KO', getDolGlobalString('ONLINE_PAYMENT_MESSAGE_KO'), '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); print ''; print ''; print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; -print ''; +print ''; print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; print ''; @@ -309,11 +309,11 @@ print "\n"; // Payment token for URL print ''; print $langs->trans("SecurityToken").''; -print ''; +print ''; if (!empty($conf->use_javascript_ajax)) { print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"'); } -if (!empty($conf->global->PAYMENT_SECURITY_ACCEPT_ANY_TOKEN)) { +if (getDolGlobalString('PAYMENT_SECURITY_ACCEPT_ANY_TOKEN')) { $langs->load("errors"); print img_warning($langs->trans("WarningTheHiddenOptionIsOn", 'PAYMENT_SECURITY_ACCEPT_ANY_TOKEN'), '', 'pictowarning marginleftonly'); } @@ -325,7 +325,7 @@ if ($conf->use_javascript_ajax) { print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE); + print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')); } print ''; @@ -367,7 +367,7 @@ if (!empty($conf->use_javascript_ajax)) { print '$(document).ready(function () { $("#apidoc").hide(); $("#apidoca").click(function() { - console.log("We click on apidoca show/hide"); + console.log("We click on apidoca so we show/hide"); $("#apidoc").show(); $("#apidoca").hide(); return false; diff --git a/htdocs/product/admin/price_rules.php b/htdocs/product/admin/price_rules.php index 4fa0c293b2d..561c8d48e90 100644 --- a/htdocs/product/admin/price_rules.php +++ b/htdocs/product/admin/price_rules.php @@ -30,7 +30,7 @@ $langs->loadLangs(array('admin', 'products')); $action = GETPOST('action', 'aZ09'); // Security check -if (!$user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled))) { +if (!$user->admin || (!isModEnabled("product") && !isModEnabled("service"))) { accessforbidden(); } @@ -119,10 +119,10 @@ while ($result = $db->fetch_object($query)) { $title = $langs->trans('ProductServiceSetup'); $tab = $langs->trans("ProductsAndServices"); -if (empty($conf->product->enabled)) { +if (!isModEnabled("product")) { $title = $langs->trans('ServiceSetup'); $tab = $langs->trans('Services'); -} elseif (empty($conf->service->enabled)) { +} elseif (!isModEnabled("service")) { $title = $langs->trans('ProductSetup'); $tab = $langs->trans('Products'); } diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 92897c45aa5..f79b8ab982e 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -41,7 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php'; $langs->loadLangs(array("admin", "products")); // Security check -if (!$user->admin || (empty($conf->product->enabled) && empty($conf->service->enabled))) { +if (!$user->admin || (!isModEnabled("product") && !isModEnabled("service"))) { accessforbidden(); } @@ -271,10 +271,10 @@ $formbarcode = new FormBarCode($db); $title = $langs->trans('ProductServiceSetup'); $tab = $langs->trans("ProductsAndServices"); -if (empty($conf->product->enabled)) { +if (!isModEnabled("product")) { $title = $langs->trans('ServiceSetup'); $tab = $langs->trans('Services'); -} elseif (empty($conf->service->enabled)) { +} elseif (!isModEnabled("service")) { $title = $langs->trans('ProductSetup'); $tab = $langs->trans('Products'); } @@ -601,7 +601,7 @@ print ''; print ''; // Use conditionnement in buying -if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { +if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { print ''; print ''.$form->textwithpicto($langs->trans("UseProductSupplierPackaging"), $langs->trans("PackagingForThisProductDesc")).''; print ''; diff --git a/htdocs/product/admin/product_extrafields.php b/htdocs/product/admin/product_extrafields.php index 4885c595097..d5b97555ba4 100644 --- a/htdocs/product/admin/product_extrafields.php +++ b/htdocs/product/admin/product_extrafields.php @@ -66,10 +66,10 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; $title = $langs->trans('ProductServiceSetup'); $textobject = $langs->trans("ProductsAndServices"); -if (empty($conf->product->enabled)) { +if (!isModEnabled("product")) { $title = $langs->trans('ServiceSetup'); $textobject = $langs->trans('Services'); -} elseif (empty($conf->service->enabled)) { +} elseif (!isModEnabled("service")) { $title = $langs->trans('ProductSetup'); $textobject = $langs->trans('Products'); } diff --git a/htdocs/product/admin/product_supplier_extrafields.php b/htdocs/product/admin/product_supplier_extrafields.php index afd46f104ae..6469c3d9b42 100644 --- a/htdocs/product/admin/product_supplier_extrafields.php +++ b/htdocs/product/admin/product_supplier_extrafields.php @@ -67,10 +67,10 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; $title = $langs->trans('ProductServiceSetup'); $textobject = $langs->trans("ProductsAndServices"); -if (empty($conf->product->enabled)) { +if (!isModEnabled("product")) { $title = $langs->trans('ServiceSetup'); $textobject = $langs->trans('Services'); -} elseif (empty($conf->service->enabled)) { +} elseif (!isModEnabled("service")) { $title = $langs->trans('ProductSetup'); $textobject = $langs->trans('Products'); } diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index e07aa4ab5c5..3f60355301f 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -20,7 +20,7 @@ /** * \file htdocs/product/ajax/products.php - * \brief File to return Ajax response on product list request. + * \brief File to return Ajax response on product list request, with default VAT rate. */ if (!defined('NOTOKENRENEWAL')) { @@ -35,9 +35,6 @@ if (!defined('NOREQUIREHTML')) { if (!defined('NOREQUIREAJAX')) { define('NOREQUIREAJAX', '1'); } -if (!defined('NOREQUIRESOC')) { - define('NOREQUIRESOC', '1'); -} if (empty($_GET['keysearch']) && !defined('NOREQUIREHTML')) { define('NOREQUIREHTML', '1'); } @@ -225,6 +222,32 @@ if ($action == 'fetch' && !empty($id)) { $outdefault_vat_code = $object->default_vat_code; } + // VAT to use and default VAT for product are set to same value by default + $product_outtva_tx_formated = $outtva_tx_formated; + $product_outtva_tx = $outtva_tx; + $product_outdefault_vat_code = $outdefault_vat_code; + + // If we ask the price according to buyer, we change it. + if (GETPOST('addalsovatforthirdpartyid', 'int')) { + $thirdparty_buyer = new Societe($db); + $thirdparty_buyer->fetch($socid); + + $tmpvatwithcode = get_default_tva($mysoc, $thirdparty_buyer, $id, 0); + + if (!is_numeric($tmpvatwithcode) || $tmpvatwithcode != -1) { + $reg =array(); + if (preg_match('/(.+)\s\((.+)\)/', $tmpvatwithcode, $reg)) { + $outtva_tx = price2num($reg[1]); + $outtva_tx_formated = price($outtva_tx); + $outdefault_vat_code = $reg[2]; + } else { + $outtva_tx = price2num($tmpvatwithcode); + $outtva_tx_formated = price($outtva_tx); + $outdefault_vat_code = ''; + } + } + } + $outjson = array( 'ref' => $outref, 'label' => $outlabel, @@ -235,13 +258,19 @@ if ($action == 'fetch' && !empty($id)) { 'price_ht' => $outprice_ht, 'price_ttc' => $outprice_ttc, 'pricebasetype' => $outpricebasetype, + 'product_tva_tx_formated' => $product_outtva_tx_formated, + 'product_tva_tx' => $product_outtva_tx, + 'product_default_vat_code' => $product_outdefault_vat_code, + 'tva_tx_formated' => $outtva_tx_formated, 'tva_tx' => $outtva_tx, 'default_vat_code' => $outdefault_vat_code, + 'qty' => $outqty, 'discount' => $outdiscount, 'mandatory_period' => $mandatory_period, - 'array_options'=>$object->array_options); + 'array_options'=>$object->array_options + ); } echo json_encode($outjson); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index f0e3f8f0b00..c2de9c24770 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -871,6 +871,7 @@ class Product extends CommonObject $langs->load("products"); $error++; $this->error = "ErrorProductAlreadyExists"; + dol_syslog(get_class($this)."::Create fails, ref ".$this->ref." already exists"); } } else { $error++; @@ -5031,10 +5032,9 @@ class Product extends CommonObject } if (!empty($this->entity)) { - $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80); + $tmpphoto = $this->show_photos('product', $conf->product->multidir_output[$this->entity], 1, 1, 0, 0, 0, 80, 0, 0, 0, 0, 1); if ($this->nbphoto > 0) { - $datas['photo'] = '
' . $tmpphoto . '
'; - //$label .= '
'; + $datas['photo'] = '
'."\n" . $tmpphoto . '
'; } } @@ -5171,9 +5171,9 @@ class Product extends CommonObject if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProduct"); - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1, 1).'"'; } - $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"'); + $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1, 1).'"' : ' title="tocomplete"'); $linkclose .= $dataparams.' class="nowraponall '.$classfortooltip.($morecss ? ' '.$morecss : '').'"'; } else { $linkclose = ' class="nowraponall'.($morecss ? ' '.$morecss : '').'"'; @@ -5207,10 +5207,10 @@ class Product extends CommonObject $result .= $linkstart; if ($withpicto) { if ($this->type == Product::TYPE_PRODUCT) { - $result .= (img_object(($notooltip ? '' : $label), 'product', ($notooltip ? 'class="paddingright"' : $dataparams.' class="paddingright '.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1)); + $result .= (img_object(($notooltip ? '' : $label), 'product', 'class="paddingright"', 0, 0, $notooltip ? 0 : 1)); } if ($this->type == Product::TYPE_SERVICE) { - $result .= (img_object(($notooltip ? '' : $label), 'service', ($notooltip ? 'class="paddingright"' : $dataparams.' class="paddingright '.$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1)); + $result .= (img_object(($notooltip ? '' : $label), 'service', 'class="paddingright"', 0, 0, $notooltip ? 0 : 1)); } } $result .= dol_escape_htmltag($newref); @@ -5635,7 +5635,7 @@ class Product extends CommonObject } $stock_sending_client = $this->stats_expedition['qty']; } - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order")) { + if (isModEnabled("supplier_order")) { $filterStatus = empty($conf->global->SUPPLIER_ORDER_STATUS_FOR_VIRTUAL_STOCK) ? '3,4' : $conf->global->SUPPLIER_ORDER_STATUS_FOR_VIRTUAL_STOCK; if (isset($includedraftpoforvirtual)) { $filterStatus = '0,1,2,'.$filterStatus; // 1,2 may have already been inside $filterStatus but it is better to have twice than missing $filterStatus does not include them @@ -5646,7 +5646,7 @@ class Product extends CommonObject } $stock_commande_fournisseur = $this->stats_commande_fournisseur['qty']; } - if (((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && empty($conf->reception->enabled)) { + if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && empty($conf->reception->enabled)) { // Case module reception is not used $filterStatus = '4'; if (isset($includedraftpoforvirtual)) { @@ -5658,7 +5658,7 @@ class Product extends CommonObject } $stock_reception_fournisseur = $this->stats_reception['qty']; } - if (((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && isModEnabled("reception")) { + if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && isModEnabled("reception")) { // Case module reception is used $filterStatus = '4'; if (isset($includedraftpoforvirtual)) { diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 6a6fe72a08a..4e40ce28dea 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -66,6 +66,7 @@ class Productcustomerprice extends CommonObject public $price_min; public $price_min_ttc; public $price_base_type; + public $default_vat_code; public $tva_tx; public $recuperableonly; public $localtax1_type; @@ -78,6 +79,9 @@ class Productcustomerprice extends CommonObject */ public $fk_user; + /** + * @var PriceByCustomerLine[] + */ public $lines = array(); @@ -871,7 +875,7 @@ class Productcustomerprice extends CommonObject $prodsocpriceupd->recuperableonly = $this->recuperableonly; $resultupd = $prodsocpriceupd->update($user, 0, $forceupdateaffiliate); - if ($result < 0) { + if ($resultupd < 0) { $error++; $this->error = $prodsocpriceupd->error; } @@ -889,7 +893,7 @@ class Productcustomerprice extends CommonObject $prodsocpricenew->recuperableonly = $this->recuperableonly; $resultupd = $prodsocpricenew->create($user, 0, $forceupdateaffiliate); - if ($result < 0) { + if ($resultupd < 0) { $error++; $this->error = $prodsocpricenew->error; } @@ -923,7 +927,7 @@ class Productcustomerprice extends CommonObject $this->db->begin(); - if (!$error && !$notrigger) { + if (!$notrigger) { $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_DELETE', $user); if ($result < 0) { $error++; diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 600bf8eb9c0..2a4217f5810 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -77,7 +77,7 @@ if ($user->socid) { $socid = $user->socid; } -if (empty($user->rights->fournisseur->lire) && (empty($conf->margin->enabled) && !$user->hasRight("margin", "liretous"))) { +if (empty($user->rights->fournisseur->lire) && (!isModEnabled('margin') && !$user->hasRight("margin", "liretous"))) { accessforbidden(); } @@ -501,7 +501,8 @@ if ($id > 0 || $ref) { } else { $events = array(); $events[] = array('method' => 'getVatRates', 'url' => dol_buildpath('/core/ajax/vatrates.php', 1), 'htmlname' => 'tva_tx', 'params' => array()); - print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', 'fournisseur=1', 'SelectThirdParty', 0, 0, $events); + $filter = '(fournisseur:=:1)'; + print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', $filter, 'SelectThirdParty', 0, 0, $events); $parameters = array('filtre'=>"fournisseur=1", 'html_name'=>'id_fourn', 'selected'=>GETPOST("id_fourn"), 'showempty'=>1, 'prod_id'=>$object->id); $reshook = $hookmanager->executeHooks('formCreateThirdpartyOptions', $parameters, $object, $action); @@ -923,7 +924,7 @@ END; $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } $param .= '&ref='.urlencode($object->ref); diff --git a/htdocs/product/index.php b/htdocs/product/index.php index a25737d5583..d31e365295f 100644 --- a/htdocs/product/index.php +++ b/htdocs/product/index.php @@ -36,10 +36,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $type = GETPOST("type", 'int'); -if ($type == '' && empty($user->rights->produit->lire)) { +if ($type == '' && !$user->hasRight('produit', 'lire') && $user->hasRight('service', 'lire')) { $type = '1'; // Force global page on service page only } -if ($type == '' && empty($user->rights->service->lire)) { +if ($type == '' && !$user->hasRight('service', 'lire') && $user->hasRight('produit', 'lire')) { $type = '0'; // Force global page on product page only } @@ -58,7 +58,7 @@ if ($type == '0') { } elseif ($type == '1') { $result = restrictedArea($user, 'service'); } else { - $result = restrictedArea($user, 'produit|service|expedition'); + $result = restrictedArea($user, 'produit|service|expedition|reception'); } @@ -73,11 +73,11 @@ if (!isset($_GET["type"])) { $transAreaType = $langs->trans("ProductsAndServicesArea"); $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; } -if ((isset($_GET["type"]) && $_GET["type"] == 0) || empty($conf->service->enabled)) { +if ((isset($_GET["type"]) && $_GET["type"] == 0) || !isModEnabled("service")) { $transAreaType = $langs->trans("ProductsArea"); $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; } -if ((isset($_GET["type"]) && $_GET["type"] == 1) || empty($conf->product->enabled)) { +if ((isset($_GET["type"]) && $_GET["type"] == 1) || !isModEnabled("product")) { $transAreaType = $langs->trans("ServicesArea"); $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; } diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index 80189f29845..275b5272d9c 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -607,9 +607,9 @@ class Inventory extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ public function getLibStatut($mode = 0) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 5f72928ed13..89f59239e7c 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -99,7 +99,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ //Parameters Page $param = '&id='.$object->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } $paramwithsearch = $param; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index c3464739589..4d654bd5187 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -702,7 +702,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($sall) { $param .= "&sall=".urlencode($sall); diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 08757602907..172ca4a5e54 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -69,8 +69,8 @@ if ($user->socid) { $socid = $user->socid; } +$object = new Product($db); if ($id > 0 || !empty($ref)) { - $object = new Product($db); $object->fetch($id, $ref); } @@ -1944,7 +1944,8 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print ''; print ''.$langs->trans('ThirdParty').''; print ''; - print img_picto('', 'company').$form->select_company('', 'socid', 's.client IN (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300'); + $filter = '(s.client:IN:1,2,3)'; + print img_picto('', 'company').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300'); print ''; print ''; diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index f22e688327a..6cb7c455759 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -5,6 +5,7 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2019 Juanjo Menent + * Copyright (C) 2023 Vincent de Grandpré * * 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 @@ -172,7 +173,44 @@ if (!empty($search_categ) && $search_categ != '-1') { } $sql .= ")"; } -$sql .= " AND EXISTS (SELECT e.rowid FROM ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = s.fk_entrepot AND e.entity IN (".getEntity('stock')."))"; +if (empty($conf->global->PRODUCT_STOCK_LIST_SHOW_VIRTUAL_WITH_NO_PHYSICAL)) { + $sql .= " AND EXISTS (SELECT e.rowid FROM ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = s.fk_entrepot AND e.entity IN (".getEntity('stock')."))"; +} else { + $sql .= " AND + ( + EXISTS + (SELECT e.rowid + FROM ".MAIN_DB_PREFIX."entrepot as e + WHERE e.rowid = s.fk_entrepot AND e.entity IN (".getEntity('stock').")) + OR ( + SELECT SUM(cd1.qty) as qty + FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as cd1 + LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur as c1 + ON c1.rowid = cd1.fk_commande + WHERE c1.entity IN (1) AND cd1.fk_product = p.rowid AND c1.fk_statut in (3,4) AND cd1.qty <> 0 + ) IS NOT NULL + OR ( + SELECT SUM(cd2.qty) as qty + FROM ".MAIN_DB_PREFIX."commandedet as cd2 + LEFT JOIN ".MAIN_DB_PREFIX."commande as c2 ON c2.rowid = cd2.fk_commande + WHERE c2.entity IN (1) AND cd2.fk_product = p.rowid AND c2.fk_statut in (1,2) AND cd2.qty <> 0 + ) IS NOT NULL + OR ( + SELECT SUM(ed3.qty) as qty + FROM ".MAIN_DB_PREFIX."expeditiondet as ed3 + LEFT JOIN ".MAIN_DB_PREFIX."expedition as e3 ON e3.rowid = ed3.fk_expedition + LEFT JOIN ".MAIN_DB_PREFIX."commandedet as cd3 ON ed3.fk_origin_line = cd3.rowid + LEFT JOIN ".MAIN_DB_PREFIX."commande as c3 ON c3.rowid = cd3.fk_commande + WHERE e3.entity IN (1) AND cd3.fk_product = p.rowid AND c3.fk_statut IN (1,2) AND e3.fk_statut IN (1,2) AND ed3.qty <> 0 + ) IS NOT NULL + OR ( + SELECT SUM(mp4.qty) as qty + FROM ".MAIN_DB_PREFIX."mrp_production as mp4 + LEFT JOIN ".MAIN_DB_PREFIX."mrp_mo as m4 ON m4.rowid = mp4.fk_mo AND m4.entity IN (1) AND m4.status IN (1,2) + WHERE mp4.fk_product = p.rowid AND mp4.qty <> 0 + ) IS NOT NULL + ) "; +} if ($sall) { $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall); } @@ -288,7 +326,7 @@ if ($resql) { $param = ''; if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($sall) { $param .= "&sall=".urlencode($sall); diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index d24b5282d11..da2c45c6766 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -6,6 +6,7 @@ * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2019 Juanjo Menent + * Copyright (C) 2021 Noé Cendrier * * 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 @@ -37,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; // Load translation files required by the page -$langs->loadLangs(array('products', 'stocks', 'productbatch')); +$langs->loadLangs(array('products', 'stocks', 'productbatch', 'categories')); $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) @@ -48,7 +49,7 @@ $mode = GETPOST('mode', 'aZ'); $sref = GETPOST("sref", 'alpha'); $snom = GETPOST("snom", 'alpha'); -$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); +$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $type = GETPOSTISSET('type') ? GETPOST('type', 'int') : Product::TYPE_PRODUCT; $search_barcode = GETPOST("search_barcode", 'alpha'); $search_warehouse = GETPOST('search_warehouse', 'alpha'); @@ -82,6 +83,7 @@ if (GETPOSTISSET('catid')) { } else { $search_categ = GETPOST('search_categ', 'int'); } +$search_warehouse_categ = GETPOST('search_warehouse_categ', 'int'); // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -135,6 +137,23 @@ if ($user->socid) { } $result = restrictedArea($user, 'produit|service', 0, 'product&product'); +// Definition of array of fields for columns +$arrayfields = array( + array('type'=>'varchar', 'label'=>'Ref', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'varchar', 'label'=>'Label', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'int', 'label'=>'Warehouse', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'varchar', 'label'=>'Lot', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'varchar', 'label'=>'DLC', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'varchar', 'label'=>'DLUO', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'int', 'label'=>'Stock', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'int', 'label'=>'StatusSell', 'checked'=>1, 'enabled'=>1, 'position'=>1), + array('type'=>'int', 'label'=>'StatusBuy', 'checked'=>1, 'enabled'=>1, 'position'=>1), +); + +//$arrayfields['anotherfield'] = array('type'=>'integer', 'label'=>'AnotherField', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right'); +$arrayfields = dol_sort_array($arrayfields, 'position'); + + /* * Actions @@ -173,11 +192,12 @@ if (empty($reshook)) { $search['eatby_dtend'] = ''; $sref = ""; $snom = ""; - $sall = ""; + $search_all = ""; $tosell = ""; $tobuy = ""; $search_sale = ""; $search_categ = ""; + $search_warehouse_categ = ""; $search_toolowstock = ''; $search_subjecttolotserial = ''; $search_batch = ''; @@ -255,8 +275,24 @@ if (!empty($search_categ) && $search_categ != '-1') { } $sql .= ")"; } -if ($sall) { - $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall); +if (!empty($search_warehouse_categ) && $search_warehouse_categ != '-1') { + $sql .= " AND "; + if ($search_warehouse_categ == -2) { + $sql .= " NOT EXISTS "; + } else { + $sql .= " EXISTS "; + } + $sql .= "("; + $sql .= " SELECT cp.fk_categorie, cp.fk_warehouse"; + $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_warehouse as cp"; + $sql .= " WHERE cp.fk_warehouse = e.rowid"; // Join for the needed table to filter by categ + if ($search_warehouse_categ > 0) { + $sql .= " AND cp.fk_categorie = " . ((int) $search_warehouse_categ); + } + $sql .= ")"; +} +if ($search_all) { + $sql .= natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $search_all); } // if the type is not 1, we show all products (type = 0,2,3) if (dol_strlen($type)) { @@ -402,7 +438,7 @@ $num = $db->num_rows($resql); $i = 0; -if ($num == 1 && GETPOST('autojumpifoneonly') && ($sall or $snom or $sref)) { +if ($num == 1 && GETPOST('autojumpifoneonly') && ($search_all or $snom or $sref)) { $objp = $db->fetch_object($resql); header("Location: card.php?id=$objp->rowid"); exit; @@ -427,7 +463,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { @@ -443,8 +479,8 @@ foreach ($search as $key => $val) { if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); } -if ($sall) { - $param .= "&sall=".urlencode($sall); +if ($search_all) { + $param .= "&search_all=".urlencode($search_all); } if ($tosell) { $param .= "&tosell=".urlencode($tosell); @@ -485,6 +521,9 @@ if ($search_sale) { if (!empty($search_categ) && $search_categ != '-1') { $param .= "&search_categ=".urlencode($search_categ); } +if (!empty($search_warehouse_categ) && $search_warehouse_categ != '-1') { + $param .= "&search_warehouse_categ=".urlencode($search_warehouse_categ); +} if ($search_stock_physique) { $param .= '&search_stock_physique=' . urlencode($search_stock_physique); } @@ -508,7 +547,7 @@ print ''; print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'product', 0, '', '', $limit, 0, 0, 1); - +/* if ($search_categ > 0) { print "
"; $c = new Categorie($db); @@ -517,17 +556,27 @@ if ($search_categ > 0) { print " > ".$ways[0]."
\n"; print "

"; } +*/ // Filter on categories $moreforfilter = ''; if (isModEnabled('categorie')) { $moreforfilter .= '
'; - $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"'); - $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1); + $moreforfilter .= img_picto($langs->trans('ProductsCategoriesShort'), 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_PRODUCT, $search_categ, 'search_categ', 1, $langs->trans("ProductsCategoryShort"), 'maxwidth400'); $moreforfilter .= '
'; } +// Filter on warehouse categories +if (isModEnabled('categorie')) { + $moreforfilter .= '
'; + $moreforfilter .= img_picto($langs->trans('StockCategoriesShort'), 'category', 'class="pictofixedwidth"'); + $moreforfilter .= $htmlother->select_categories(Categorie::TYPE_WAREHOUSE, $search_warehouse_categ, 'search_warehouse_categ', 1, $langs->trans("StockCategoriesShort"), 'maxwidth400'); + $moreforfilter .= '
'; +} + $moreforfilter.=''; + if (!empty($moreforfilter)) { print '
'; print $moreforfilter; @@ -552,18 +601,19 @@ if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; } print ''; -print ''; +print ''; print ''; print ''; -print ''; +print ''; print ''; if (isModEnabled("service") && $type == 1) { print ''; print ' '; print ''; } -print ''; -print ''; + +print ''; +print ''; if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { print ''; $key = 'sellby'; @@ -701,6 +751,9 @@ while ($i < $imaxinloop) { // Action column if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Ref @@ -708,9 +761,15 @@ while ($i < $imaxinloop) { print $product_static->getNomUrl(1, '', 16); //if ($objp->stock_theorique < $objp->seuil_stock_alerte) print ' '.img_warning($langs->trans("StockTooLow")); print ''; + if (!$i) { + $totalarray['nbfield']++; + } // Label print ''.$objp->label.''; + if (!$i) { + $totalarray['nbfield']++; + } if (isModEnabled("service") && $type == 1) { print ''; @@ -724,6 +783,9 @@ while ($i < $imaxinloop) { } else { print $objp->duration; } + if (!$i) { + $totalarray['nbfield']++; + } print ''; } //print ''.$objp->stock_theorique.''; @@ -735,6 +797,9 @@ while ($i < $imaxinloop) { if ($objp->fk_entrepot > 0) { print $warehousetmp->getNomUrl(1); } + if (!$i) { + $totalarray['nbfield']++; + } print ''; // Lot @@ -742,14 +807,23 @@ while ($i < $imaxinloop) { if ($product_lot_static->batch) { print $product_lot_static->getNomUrl(1); } + if (!$i) { + $totalarray['nbfield']++; + } print ''; if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { print ''.dol_print_date($db->jdate($objp->sellby), 'day').''; + if (!$i) { + $totalarray['nbfield']++; + } } if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { print ''.dol_print_date($db->jdate($objp->eatby), 'day').''; + if (!$i) { + $totalarray['nbfield']++; + } } print ''; @@ -768,15 +842,27 @@ while ($i < $imaxinloop) { } } print ''; + if (!$i) { + $totalarray['nbfield']++; + } print ''; print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"'); print ''.$langs->trans("Movements").''; print ''; + if (!$i) { + $totalarray['nbfield']++; + } print ''.$product_static->LibStatut($objp->statut, 5, 0).''; + if (!$i) { + $totalarray['nbfield']++; + } print ''.$product_static->LibStatut($objp->tobuy, 5, 1).''; + if (!$i) { + $totalarray['nbfield']++; + } // Fields values from hook $parameters = array('obj'=>$objp); @@ -786,12 +872,27 @@ while ($i < $imaxinloop) { // Action column if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { print ''; + if (!$i) { + $totalarray['nbfield']++; + } } print "\n"; $i++; } +// If no record found +if ($num == 0) { + $colspan = 2; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''.$langs->trans("NoRecordFound").''; +} + + $db->free($resql); print ''."\n"; diff --git a/htdocs/product/stats/bom.php b/htdocs/product/stats/bom.php index 0ccc249b94f..d417fc8af73 100644 --- a/htdocs/product/stats/bom.php +++ b/htdocs/product/stats/bom.php @@ -262,7 +262,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index d5854fdc702..a8606e49a8f 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -188,7 +188,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index 4d5972529cd..dddd911224c 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -188,7 +188,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/contrat.php b/htdocs/product/stats/contrat.php index a53c71085fd..21737badb16 100644 --- a/htdocs/product/stats/contrat.php +++ b/htdocs/product/stats/contrat.php @@ -173,7 +173,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index c0a4d36793c..f17d56faeb9 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -204,7 +204,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index 8e89a05273f..06a63cb4c6e 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -187,7 +187,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/facturerec.php b/htdocs/product/stats/facturerec.php index d1bbfe54e57..ddc7e1a0e3d 100644 --- a/htdocs/product/stats/facturerec.php +++ b/htdocs/product/stats/facturerec.php @@ -205,7 +205,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/mo.php b/htdocs/product/stats/mo.php index 561557e62fe..8a4fc03b530 100644 --- a/htdocs/product/stats/mo.php +++ b/htdocs/product/stats/mo.php @@ -183,7 +183,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index e1b46677c65..99f3e42e921 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -189,7 +189,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stats/supplier_proposal.php b/htdocs/product/stats/supplier_proposal.php index a182aa61eb6..841c0e29004 100644 --- a/htdocs/product/stats/supplier_proposal.php +++ b/htdocs/product/stats/supplier_proposal.php @@ -188,7 +188,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$product->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php index ee67248c939..8478a021b34 100644 --- a/htdocs/product/stock/card.php +++ b/htdocs/product/stock/card.php @@ -403,9 +403,7 @@ if ($action == 'create') { exit; } - /* - * Affichage fiche - */ + // View mode if ($action <> 'edit' && $action <> 're-edit') { $head = stock_prepare_head($object); @@ -593,13 +591,12 @@ if ($action == 'create') { print "
"; - /* ************************************************************************** */ - /* */ - /* Affichage de la liste des produits de l'entrepot */ - /* */ - /* ************************************************************************** */ + // Show list of products into warehouse print '
'; + + // TODO Create $arrayfields with all fields to show + print ''; print ""; $parameters = array(); @@ -734,6 +731,7 @@ if ($action == 'create') { $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_buy_intra; $productstatic->accountancy_code_buy_export = $objp->accountancy_code_buy_export; + // Ref print "'; @@ -741,6 +739,7 @@ if ($action == 'create') { // Label print ''; + // Value print ''; } + // Price buy PMP print ''; @@ -776,6 +776,7 @@ if ($action == 'create') { } $totalvaluesell += price2num($pricemin * $objp->value, 'MT'); + // Link to transfer if ($user->rights->stock->mouvement->creer) { print '"; } + // Link to stock if ($user->rights->stock->creer) { print '"; } + print ""; + + $i++; + + // Define $unit and $sameunits if (!empty($conf->global->PRODUCT_USE_UNITS)) { if ($i == 0) { $units = $productstatic->fk_unit; @@ -797,9 +804,6 @@ if ($action == 'create') { $sameunits = false; } } - - print ""; - $i++; } $db->free($resql); @@ -838,9 +842,7 @@ if ($action == 'create') { } - /* - * Edit - */ + // Edit mode if ($action == 'edit' || $action == 're-edit') { $langs->trans("WarehouseEdit"); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 8ab5ff77da4..b596ac551b1 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -301,7 +301,9 @@ class MouvementStock extends CommonObject // If not found, we add record $sql = "SELECT pb.rowid, pb.batch, pb.eatby, pb.sellby FROM ".$this->db->prefix()."product_lot as pb"; $sql .= " WHERE pb.fk_product = ".((int) $fk_product)." AND pb.batch = '".$this->db->escape($batch)."'"; + dol_syslog(get_class($this)."::_create scan serial for this product to check if eatby and sellby match", LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -560,6 +562,10 @@ class MouvementStock extends CommonObject if (!$error && isModEnabled('productbatch') && $product->hasbatch() && !$skip_batch) { if ($id_product_batch > 0) { $result = $this->createBatch($id_product_batch, $qty); + if ($result == -2 && $fk_product_stock > 0) { // The entry for this product batch does not exists anymore, bu we already have a llx_product_stock, so we recreate the batch entry in product_batch + $param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch); + $result = $this->createBatch($param_batch, $qty); + } } else { $param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch); $result = $this->createBatch($param_batch, $qty); @@ -863,10 +869,10 @@ class MouvementStock extends CommonObject * Create or update batch record (update table llx_product_batch). No check is done here, done by parent. * * @param array|int $dluo Could be either - * - int if row id of product_batch table + * - int if row id of product_batch table (for update) * - or complete array('fk_product_stock'=>, 'batchnumber'=>) * @param int $qty Quantity of product with batch number. May be a negative amount. - * @return int <0 if KO, else return productbatch id + * @return int <0 if KO, -2 if we try to update a product_batchid that does not exist, else return productbatch id */ private function createBatch($dluo, $qty) { @@ -1154,10 +1160,10 @@ class MouvementStock extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un status donne + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function LibStatut($mode = 0) { diff --git a/htdocs/product/stock/class/productstockentrepot.class.php b/htdocs/product/stock/class/productstockentrepot.class.php index 1151890a4b1..1856b7b156d 100644 --- a/htdocs/product/stock/class/productstockentrepot.class.php +++ b/htdocs/product/stock/class/productstockentrepot.class.php @@ -532,9 +532,9 @@ class ProductStockEntrepot extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ public function getLibStatut($mode = 0) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 3201bb5f507..f731c6e855f 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -385,7 +385,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/product/stock/movement_card.php b/htdocs/product/stock/movement_card.php index e28dcc5ca51..5babcfc4c7c 100644 --- a/htdocs/product/stock/movement_card.php +++ b/htdocs/product/stock/movement_card.php @@ -685,7 +685,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($id > 0) { $param .= '&id='.urlencode($id); diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php index 09f1975bcb4..72f36220185 100644 --- a/htdocs/product/stock/movement_list.php +++ b/htdocs/product/stock/movement_list.php @@ -50,20 +50,23 @@ if (isModEnabled('productbatch')) { $langs->load("productbatch"); } -$id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); -$msid = GETPOST('msid', 'int'); -$product_id = GETPOST("product_id", 'int'); $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $cancel = GETPOST('cancel', 'alpha'); -$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'movementlist'; +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list $backtopage = GETPOST("backtopage", "alpha"); +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...) +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$msid = GETPOST('msid', 'int'); $idproduct = GETPOST('idproduct', 'int'); -$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); +$product_id = GETPOST("product_id", 'int'); + +$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $search_date_startday = GETPOST('search_date_startday', 'int'); $search_date_startmonth = GETPOST('search_date_startmonth', 'int'); $search_date_startyear = GETPOST('search_date_startyear', 'int'); @@ -83,7 +86,7 @@ $search_batch = trim(GETPOST("search_batch")); $search_qty = trim(GETPOST("search_qty")); $search_type_mouvement = GETPOST('search_type_mouvement', 'int'); $search_fk_projet=GETPOST("search_fk_projet", 'int'); -$optioncss = GETPOST('optioncss', 'alpha'); + $type = GETPOST("type", "int"); // Load variable for pagination @@ -108,15 +111,15 @@ if (!$sortorder) { $pdluoid = GETPOST('pdluoid', 'int'); -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +// Initialize technical objects $object = new MouvementStock($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('movementlist')); +$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes $formfile = new FormFile($db); -// fetch optionals attributes and labels +// Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); @@ -224,7 +227,7 @@ if (empty($reshook)) { $search_batch = ""; $search_qty = ''; $search_fk_projet=0; - $sall = ""; + $search_all = ""; $toselect = array(); $search_array_options = array(); } @@ -588,18 +591,21 @@ if ($action == "transfert_stock" && !$cancel) { * View */ -$productlot = new ProductLot($db); -$productstatic = new Product($db); -$warehousestatic = new Entrepot($db); -$movement = new MouvementStock($db); -$userstatic = new User($db); $form = new Form($db); $formproduct = new FormProduct($db); if (!empty($conf->project->enabled)) { $formproject = new FormProjets($db); } +$productlot = new ProductLot($db); +$productstatic = new Product($db); +$warehousestatic = new Entrepot($db); +$movement = new MouvementStock($db); +$userstatic = new User($db); + +$now = dol_now(); // Build and execute select +// -------------------------------------------------------------------- $sql = "SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tosell, p.tobuy, p.tobatch, p.fk_product_type as type, p.entity,"; $sql .= " e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu, e.fk_parent, e.statut,"; $sql .= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,"; @@ -616,7 +622,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { } // Add fields from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql = preg_replace('/,\s*$/', '', $sql); @@ -697,7 +703,7 @@ if ($search_type_mouvement != '' && $search_type_mouvement != '-1') { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Count total nb of records @@ -714,7 +720,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } @@ -733,6 +739,9 @@ if (!$resql) { exit; } +$num = $db->num_rows($resql); + + $product = new Product($db); $object = new Entrepot($db); @@ -746,8 +755,6 @@ if ($id > 0 || $ref) { } } -$num = $db->num_rows($resql); - // Output page // -------------------------------------------------------------------- @@ -767,9 +774,11 @@ if ($msid) { } } -llxHeader('', $title, $help_url); -$arrayofselected = is_array($toselect) ? $toselect : array(); +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url); /* * Show tab only if we ask a particular warehouse @@ -939,12 +948,17 @@ if ((empty($action) || $action == 'list') && $id > 0) { print '
'; } +$arrayofselected = is_array($toselect) ? $toselect : array(); + $param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($id > 0) { $param .= '&id='.urlencode($id); @@ -996,6 +1010,10 @@ if ($idproduct > 0) { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array(); @@ -1023,10 +1041,15 @@ print ''; print ''; print ''; print ''; +print ''; +print ''; if ($id > 0) { print ''; } + +$newcardbutton = ''; + if ($id > 0) { print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'movement', 0, '', '', $limit, 0, 0, 1); } else { @@ -1040,17 +1063,20 @@ $objecttmp = new MouvementStock($db); $trackid = 'mov'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; -if ($sall) { +if ($search_all) { + $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key."=".$val.";"; } - print '
'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
'; + print ''."\n"; + print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'."\n"; } $moreforfilter = ''; $parameters = array('arrayfields'=>&$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $moreforfilter .= $hookmanager->resPrint; } else { @@ -1064,7 +1090,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table @@ -1073,6 +1099,13 @@ print '
"; print $productstatic->getNomUrl(1, 'stock', 16); print ''.dol_escape_htmltag($objp->produit).''; $valtoshow = price(price2num($objp->value, 'MS'), 0, '', 0, 0); // TODO replace with a qty() function print empty($valtoshow) ? '0' : $valtoshow; @@ -756,6 +755,7 @@ if ($action == 'create') { print $langs->trans($productstatic->getLabelOfUnit()); print ''.price(price2num($objp->ppmp, 'MU')).''; print img_picto($langs->trans("TransferStock"), 'add', 'class="hideonsmartphone pictofixedwidth" style="color: #a69944"'); @@ -783,6 +784,7 @@ if ($action == 'create') { print "'; print img_picto($langs->trans("CorrectStock"), 'add', 'class="hideonsmartphone pictofixedwidth" style="color: #a69944"'); @@ -790,6 +792,11 @@ if ($action == 'create') { print "
'; +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} if (!empty($arrayfields['m.rowid']['checked'])) { // Ref print ''; } // Action column -print ''; +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} print ''."\n"; +$totalarray = array(); +$totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; +} if (!empty($arrayfields['m.rowid']['checked'])) { print_liste_field_titre($arrayfields['m.rowid']['label'], $_SERVER["PHP_SELF"], 'm.rowid', '', $param, '', $sortfield, $sortorder); } @@ -1262,8 +1304,8 @@ if (!empty($arrayfields['m.price']['checked'])) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields -$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['m.datec']['checked'])) { print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap '); @@ -1272,7 +1314,10 @@ if (!empty($arrayfields['m.tms']['checked'])) { print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap '); } // Action column -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; +} print ''."\n"; @@ -1282,9 +1327,11 @@ $arrayofuniqueproduct = array(); // Loop on record // -------------------------------------------------------------------- $i = 0; +$savnbfield = $totalarray['nbfield']; $totalarray = array(); $totalarray['nbfield'] = 0; -while ($i < ($limit ? min($num, $limit) : $num)) { +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); if (empty($obj)) { break; // Should not happen @@ -1346,139 +1393,193 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $origin = ''; } - print ''; - // Id movement - if (!empty($arrayfields['m.rowid']['checked'])) { - print ''; // This is primary not movement id - } - if (!empty($arrayfields['m.datem']['checked'])) { - // Date - print ''; - } - if (!empty($arrayfields['p.ref']['checked'])) { - // Product ref - print '\n"; - } - if (!empty($arrayfields['p.label']['checked'])) { - // Product label - print '\n"; - } - if (!empty($arrayfields['m.batch']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.eatby']['checked'])) { - print ''; - } - if (!empty($arrayfields['pl.sellby']['checked'])) { - print ''; - } - // Warehouse - if (!empty($arrayfields['e.ref']['checked'])) { - print '\n"; - } - // Author - if (!empty($arrayfields['m.fk_user_author']['checked'])) { - print '\n"; - } - if (!empty($arrayfields['m.inventorycode']['checked'])) { - // Inventory code - print ''; - } - if (!empty($arrayfields['m.label']['checked'])) { - // Label of movement - print ''; - } - if (!empty($arrayfields['origin']['checked'])) { - // Origin of movement - print ''; - } - if (!empty($arrayfields['m.fk_projet']['checked'])) { - // fk_project - print ''; - } - if (!empty($arrayfields['m.type_mouvement']['checked'])) { - // Type of movement - print ''; - } - if (!empty($arrayfields['m.value']['checked'])) { - // Qty - print ''; } - print ''; - } - if (!empty($arrayfields['m.price']['checked'])) { - // Price - print ''; + // Action column + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Id movement + if (!empty($arrayfields['m.rowid']['checked'])) { + print ''; // This is primary not movement id + } + if (!empty($arrayfields['m.datem']['checked'])) { + // Date + print ''; + } + if (!empty($arrayfields['p.ref']['checked'])) { + // Product ref + print '\n"; + } + if (!empty($arrayfields['p.label']['checked'])) { + // Product label + print '\n"; + } + if (!empty($arrayfields['m.batch']['checked'])) { + print ''; + } + if (!empty($arrayfields['pl.eatby']['checked'])) { + print ''; + } + if (!empty($arrayfields['pl.sellby']['checked'])) { + print ''; + } + // Warehouse + if (!empty($arrayfields['e.ref']['checked'])) { + print '\n"; + } + // Author + if (!empty($arrayfields['m.fk_user_author']['checked'])) { + print '\n"; + } + if (!empty($arrayfields['m.inventorycode']['checked'])) { + // Inventory code + print ''; + } + if (!empty($arrayfields['m.label']['checked'])) { + // Label of movement + print ''; + } + if (!empty($arrayfields['origin']['checked'])) { + // Origin of movement + print ''; + } + if (!empty($arrayfields['m.fk_projet']['checked'])) { + // fk_project + print ''; + } + if (!empty($arrayfields['m.type_mouvement']['checked'])) { + // Type of movement + print ''; + } + if (!empty($arrayfields['m.value']['checked'])) { + // Qty + print ''; + } + if (!empty($arrayfields['m.price']['checked'])) { + // Price + print ''; } - print ''; - } - // Extra fields - $object = $movement; - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; + // Extra fields + $object = $movement; + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; - // Action column - print ''; + if (!$i) { + $totalarray['nbfield']++; + } } - print ''; - } - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - print ''."\n"; + print ''."\n"; + } $i++; } +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; +} + $db->free($resql); -print "
'; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; @@ -1185,7 +1218,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['m.datec']['checked'])) { @@ -1198,16 +1231,25 @@ if (!empty($arrayfields['m.tms']['checked'])) { print ''; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'; - print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"'); - print $obj->mid; - print ''.dol_print_date($db->jdate($obj->datem), 'dayhour', 'tzuserrel').''; - print $productstatic->getNomUrl(1, 'stock', 16); - print "'; - print $productstatic->label; - print "'; - if ($productlot->id > 0) { - print $productlot->getNomUrl(1); - } else { - print $productlot->batch; // the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement. + if ($mode == 'kanban') { + if ($i == 0) { + print '
'; + print '
'; } - print '
'.dol_print_date($obj->eatby, 'day').''.dol_print_date($obj->sellby, 'day').''; - print $warehousestatic->getNomUrl(1); - print "'; - print $userstatic->getNomUrl(-1); - print "inventorycode.'$').'&search_type_mouvement='.urlencode($obj->type_mouvement).'">'.$obj->inventorycode.''.$obj->label.''.$origin.''; - if ($obj->fk_project != 0) { - print $movement->get_origin($obj->fk_project, 'project'); + // Output Kanban + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } } - print ''; - print $movement->getTypeMovement(); - print ''; - if ($obj->qty > 0) { - print ''; - print '+'; - print $obj->qty; - print ''; - } else { - print ''; - print $obj->qty; - print ''; + print $object->getKanbanView(''); + if ($i == ($imaxinloop - 1)) { + print ''; + print '
'; - if ($obj->price != 0) { - print price($obj->price); + } else { + // Show here line of result + $j = 0; + print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->mid, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print ''; + print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"'); + print $obj->mid; + print ''.dol_print_date($db->jdate($obj->datem), 'dayhour', 'tzuserrel').''; + print $productstatic->getNomUrl(1, 'stock', 16); + print "'; + print $productstatic->label; + print "'; + if ($productlot->id > 0) { + print $productlot->getNomUrl(1); + } else { + print $productlot->batch; // the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement. + } + print ''.dol_print_date($obj->eatby, 'day').''.dol_print_date($obj->sellby, 'day').''; + print $warehousestatic->getNomUrl(1); + print "'; + print $userstatic->getNomUrl(-1); + print "inventorycode.'$').'&search_type_mouvement='.urlencode($obj->type_mouvement).'">'.$obj->inventorycode.''.$obj->label.''.$origin.''; + if ($obj->fk_project != 0) { + print $movement->get_origin($obj->fk_project, 'project'); + } + print ''; + print $movement->getTypeMovement(); + print ''; + if ($obj->qty > 0) { + print ''; + print '+'; + print $obj->qty; + print ''; + } else { + print ''; + print $obj->qty; + print ''; + } + print ''; + if ($obj->price != 0) { + print price($obj->price); + } + print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->mid, $arrayofselected)) { - $selected = 1; + // Action column + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->mid, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'.$langs->trans("NoRecordFound").'
"; -print '
'; -print ""; +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print ''."\n"; +print '
'."\n"; + +print ''."\n"; // Add number of product when there is a filter on period if (count($arrayofuniqueproduct) == 1 && !empty($year) && is_numeric($year)) { @@ -1527,7 +1628,7 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $genallowed = $permissiontoread; $delallowed = $permissiontoadd; - print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); + print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } // End of page diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 80a5f969a84..7befa095142 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -813,7 +813,7 @@ if ($id > 0 || $ref) { } // Number of supplier order running - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { + if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { if ($found) { $helpondiff .= '
'; } else { @@ -829,7 +829,7 @@ if ($id > 0 || $ref) { } // Number of product from supplier order already received (partial receipt) - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { + if (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) { if ($found) { $helpondiff .= '
'; } else { diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index ef6315446aa..d77075bdd8b 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -371,7 +371,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index aad386ce444..63d44bbc284 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -440,7 +440,7 @@ if ($usevirtualstock) { $sqlExpeditionsCli = '0'; } - if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order")) { + if (isModEnabled("supplier_order")) { $sqlCommandesFourn = "(SELECT ".$db->ifsql("SUM(cd3.qty) IS NULL", "0", "SUM(cd3.qty)")." as qty"; // We need the ifsql because if result is 0 for product p.rowid, we must return 0 and not NULL $sqlCommandesFourn .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as cd3,"; $sqlCommandesFourn .= " ".MAIN_DB_PREFIX."commande_fournisseur as c3"; @@ -615,7 +615,8 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) { print ''; } print '
'; -print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', 'fournisseur=1', 1); +$filter = '(fournisseur:=:1)'; +print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', $filter, 1); print '
'; $parameters = array(); @@ -669,7 +670,7 @@ if ($search_ref || $search_label || $sall || $salert || $draftorder || GETPOST(' } } if ($limit > 0 && $limit != $conf->liste_limit) { - $filters .= '&limit='.urlencode($limit); + $filters .= '&limit='.((int) $limit); } if (!empty($includeproductswithoutdesiredqty)) $filters .= '&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty); if (!empty($salert)) $filters .= '&salert='.urlencode($salert); diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php index c3c031b14bd..6695a1ce874 100644 --- a/htdocs/product/stock/replenishorders.php +++ b/htdocs/product/stock/replenishorders.php @@ -187,7 +187,7 @@ if ($resql) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($sref) { $param .= '&search_ref='.urlencode($sref); diff --git a/htdocs/product/stock/stats/commande_fournisseur.php b/htdocs/product/stock/stats/commande_fournisseur.php index 22be071ffc5..34f0a75109e 100644 --- a/htdocs/product/stock/stats/commande_fournisseur.php +++ b/htdocs/product/stock/stats/commande_fournisseur.php @@ -263,7 +263,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$object->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stock/stats/expedition.php b/htdocs/product/stock/stats/expedition.php index 79beefa40cb..d4672fb31c5 100644 --- a/htdocs/product/stock/stats/expedition.php +++ b/htdocs/product/stock/stats/expedition.php @@ -262,7 +262,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$object->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stock/stats/mo.php b/htdocs/product/stock/stats/mo.php index f0be40d1a1d..95fbb7d9e9a 100644 --- a/htdocs/product/stock/stats/mo.php +++ b/htdocs/product/stock/stats/mo.php @@ -204,7 +204,7 @@ if ($id > 0 || !empty($ref)) { $option = '&id='.$object->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stock/stats/reception.php b/htdocs/product/stock/stats/reception.php index 4e80dcf05f2..444629cd3ff 100644 --- a/htdocs/product/stock/stats/reception.php +++ b/htdocs/product/stock/stats/reception.php @@ -261,7 +261,7 @@ if ($id > 0 || !empty($ref)) { $option .= '&id='.$object->id; if ($limit > 0 && $limit != $conf->liste_limit) { - $option .= '&limit='.urlencode($limit); + $option .= '&limit='.((int) $limit); } if (!empty($search_month)) { $option .= '&search_month='.urlencode($search_month); diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index 46c902238de..76d4958da34 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -397,7 +397,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } $param .= '&mode='.$mode; if (!empty($search_fk_warehouse)) { diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php index 893bbf05ff6..55545a6868c 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_agenda.php @@ -214,7 +214,7 @@ if ($object->id > 0) { if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { $param = '&id='.$object->id.'&socid='.$socid; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); - if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); + if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.((int) $limit); //print load_fiche_titre($langs->trans("ActionsOnStockTransfer"), '', ''); diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_list.php b/htdocs/product/stock/stocktransfer/stocktransfer_list.php index 2a57b3f2f94..47904825ca7 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_list.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_list.php @@ -289,7 +289,7 @@ $arrayofselected = is_array($toselect) ? $toselect : array(); $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); -if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); +if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.((int) $limit); foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) foreach ($search[$key] as $skey) $param .= '&search_'.$key.'[]='.urlencode($skey); else $param .= '&search_'.$key.'='.urlencode($search[$key]); diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php index 93da1e218e4..ccd5b0b88db 100644 --- a/htdocs/projet/activity/index.php +++ b/htdocs/projet/activity/index.php @@ -231,7 +231,7 @@ if ($db->type != 'pgsql') $sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.task_duration) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " , ".MAIN_DB_PREFIX."projet_task as t"; - $sql.= " , ".MAIN_DB_PREFIX."projet_task_time as tt"; + $sql.= " , ".MAIN_DB_PREFIX."element_time as tt"; $sql.= " WHERE t.fk_projet = p.rowid"; $sql.= " AND p.entity = ".((int) $conf->entity); $sql.= " AND tt.fk_task = t.rowid"; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index e2f01f73738..9c4e47037c2 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -495,8 +495,7 @@ print '
'; $moreforfilter = ''; // Filter on categories -/*if (!empty($conf->categorie->enabled)) -{ +/*if (isModEnabled("categorie")) { require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $moreforfilter.='
'; $moreforfilter.=$langs->trans('ProjectCategories'). ': '; @@ -719,7 +718,7 @@ if (count($tasksarray) > 0) { $totalforeachday = array(); foreach ($listofdistinctprojectid as $tmpprojectid) { $projectstatic->id = $tmpprojectid; - $projectstatic->loadTimeSpent($daytoparse, 0, $usertoprocess->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpent($daytoparse, 0, $usertoprocess->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week for ($idw = 0; $idw < 7; $idw++) { $tmpday = dol_time_plus_duree($daytoparse, $idw, 'd'); $totalforeachday[$tmpday] += $projectstatic->weekWorkLoad[$tmpday]; diff --git a/htdocs/projet/activity/permonth.php b/htdocs/projet/activity/permonth.php index 066621f3083..bff135b713f 100644 --- a/htdocs/projet/activity/permonth.php +++ b/htdocs/projet/activity/permonth.php @@ -410,8 +410,7 @@ $moreforfilter = ''; // Filter on categories /* -if (!empty($conf->categorie->enabled)) -{ +if (isModEnabled("categorie")) { require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $moreforfilter.='
'; $moreforfilter.=$langs->trans('ProjectCategories'). ': '; @@ -536,7 +535,7 @@ if (count($tasksarray) > 0) { $totalforeachweek = array(); foreach ($listofdistinctprojectid as $tmpprojectid) { $projectstatic->id = $tmpprojectid; - $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $usertoprocess->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $usertoprocess->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week foreach ($TWeek as $weekNb) { $totalforeachweek[$weekNb] += $projectstatic->monthWorkLoad[$weekNb]; } diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index d2cb15791b1..1d3a6ef3c2c 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -546,8 +546,7 @@ $moreforfilter = ''; // Filter on categories /* - if (!empty($conf->categorie->enabled)) - { + if (isModEnabled("categorie")) { require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; $moreforfilter.='
'; $moreforfilter.=$langs->trans('ProjectCategories'). ': '; @@ -758,7 +757,7 @@ if (count($tasksarray) > 0) { $totalforeachday = array(); foreach ($listofdistinctprojectid as $tmpprojectid) { $projectstatic->id = $tmpprojectid; - $projectstatic->loadTimeSpent($firstdaytoshow, 0, $usertoprocess->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $projectstatic->loadTimeSpent($firstdaytoshow, 0, $usertoprocess->id); // Load time spent from table element_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week for ($idw = 0; $idw < 7; $idw++) { $tmpday = dol_time_plus_duree($firstdaytoshow, $idw, 'd'); $totalforeachday[$tmpday] += $projectstatic->weekWorkLoad[$tmpday]; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 42833785c09..43c31a23776 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -698,11 +698,11 @@ if ($action == 'create' && $user->rights->projet->creer) { print $langs->trans("ThirdParty"); print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : ''); print ''; - $filteronlist = ''; + $filter = ''; if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) { - $filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; + $filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; } - $text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500'); + $text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty"); print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1); @@ -910,7 +910,7 @@ if ($action == 'create' && $user->rights->projet->creer) { if ($action == 'clone') { $formquestion = array( 'text' => $langs->trans("ConfirmClone"), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ?GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')), + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ? GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')), array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true), array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true), array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true), @@ -1077,12 +1077,12 @@ if ($action == 'create' && $user->rights->projet->creer) { print $langs->trans("ThirdParty"); print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : ''); print ''; - $filteronlist = ''; + $filter = ''; if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) { - $filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; + $filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; } $text = img_picto('', 'company', 'class="pictofixedwidth"'); - $text .= $form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300'); + $text .= $form->select_company($object->thirdparty->id, 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty"); print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2); @@ -1159,11 +1159,14 @@ if ($action == 'create' && $user->rights->projet->creer) { print $form->selectDate($object->date_start ? $object->date_start : -1, 'projectstart', 0, 0, 0, '', 1, 0); print ' '.$langs->trans("to").' '; print $form->selectDate($object->date_end ? $object->date_end : -1, 'projectend', 0, 0, 0, '', 1, 0); - print '     getLinesArray(null, 0); + if (!empty($object->usage_task) && !empty($object->lines)) { + print ' '; } - print '/>'; print ''; if (isModEnabled('eventorganization')) { @@ -1385,6 +1388,11 @@ if ($action == 'create' && $user->rights->projet->creer) { jQuery("#usage_task").prop("checked", true); } }); + + jQuery("#projectstart").change(function() { + console.log("We modify the start date"); + jQuery("#divreportdate").show(); + }); }); '; diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 9f00d4ce3c0..c3ef972d52c 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -291,7 +291,7 @@ class Project extends CommonObject 'date_close' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>0, 'position'=>105), 'fk_user_close' =>array('type'=>'integer', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>0, 'position'=>110), 'opp_amount' =>array('type'=>'double(24,8)', 'label'=>'OpportunityAmountShort', 'enabled'=>1, 'visible'=>'getDolGlobalString("PROJECT_USE_OPPORTUNITIES")', 'position'=>115), - 'budget_amount' =>array('type'=>'double(24,8)', 'label'=>'Budget', 'enabled'=>1, 'visible'=>1, 'position'=>119), + 'budget_amount' =>array('type'=>'double(24,8)', 'label'=>'Budget', 'enabled'=>1, 'visible'=>-1, 'position'=>119), 'usage_bill_time' =>array('type'=>'integer', 'label'=>'UsageBillTimeShort', 'enabled'=>1, 'visible'=>-1, 'position'=>130), 'usage_opportunity' =>array('type'=>'integer', 'label'=>'UsageOpportunity', 'enabled'=>1, 'visible'=>-1, 'position'=>135), 'usage_task' =>array('type'=>'integer', 'label'=>'UsageTasks', 'enabled'=>1, 'visible'=>-1, 'position'=>140), @@ -311,7 +311,7 @@ class Project extends CommonObject 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>410), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>0, 'position'=>415), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>420), - 'email_msgid'=>array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'enabled'=>1, 'visible'=>-1, 'position'=>450, 'help'=>'EmailMsgIDWhenSourceisEmail'), + 'email_msgid'=>array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'enabled'=>1, 'visible'=>-1, 'position'=>450, 'help'=>'EmailMsgIDWhenSourceisEmail', 'csslist'=>'tdoverflowmax125'), 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>500), ); // END MODULEBUILDER PROPERTIES @@ -1383,7 +1383,7 @@ class Project extends CommonObject $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="pictofixedwidth"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'pictofixedwidth ' : '').$classfortooltip.' pictofixedwidth em088"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $picto, 'class="pictofixedwidth em088"', 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; @@ -2344,11 +2344,11 @@ class Project extends CommonObject /** - * Create an array of tasks of current project + * Create an array of tasks of current project * - * @param User $user Object user we want project allowed to + * @param User $user Object user we want project allowed to * @param int $loadRoleMode 1= will test Roles on task; 0 used in delete project action - * @return int >0 if OK, <0 if KO + * @return int >0 if OK, <0 if KO */ public function getLinesArray($user, $loadRoleMode = 1) { diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index fe00eb671d9..65de5cf22c3 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -796,7 +796,7 @@ class Task extends CommonObjectLine $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), $picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $label), $picto, 'class="paddingright"', 0, 0, $notooltip ? 0 : 1); } if ($withpicto != 2) { $result .= $this->ref; @@ -2364,7 +2364,7 @@ class Task extends CommonObjectLine $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); $return = '
'; - $return .= '
'; + $return .= '
'; $return .= ''; $return .= img_picto('', $this->picto); //$return .= ''; // Can be image @@ -2372,17 +2372,16 @@ class Task extends CommonObjectLine $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; $return .= ''; - if (property_exists($this, 'fk_project') ) { - $return .= '
'.$this->fk_project.''; + if (!empty($arraydata['projectlink'])) { + //$tmpproject = $arraydata['project']; + //$return .= '
'.$tmpproject->getNomProject().''; + $return .= '
'.$arraydata['projectlink'].''; } if (property_exists($this, 'budget_amount')) { - $return .= '
'.$langs->trans("Budget").' : '.price($this->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; - } - if (property_exists($this, 'fk_statut')) { - $return .= '
'.$this->fk_statut.''; + //$return .= '
'.$langs->trans("Budget").' : '.price($this->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; } if (property_exists($this, 'duration_effective')) { - $return .= '
'.getTaskProgressView($this, false, false).'
'; + $return .= '

'.getTaskProgressView($this, false, true).'
'; } $return .= '
'; $return .= '
'; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index a737ffce640..43526abf0ab 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -54,10 +54,10 @@ if (isModEnabled('commande')) { if (isModEnabled('supplier_proposal')) { require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; } -if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_invoice")) { +if (isModEnabled("supplier_invoice")) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; } -if ((isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled("supplier_order")) { +if (isModEnabled("supplier_order")) { require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; } if (isModEnabled('contrat')) { @@ -412,7 +412,7 @@ $listofreferent = array( 'lang'=>'bills', 'buttonnew'=>'CreateBill', 'testnew'=>$user->hasRight('facture', 'creer'), - 'test'=>!empty($conf->facture->enabled) && $user->hasRight('facture', 'lire')), + 'test'=>isModEnabled('facture') && $user->hasRight('facture', 'lire')), 'invoice_predefined'=>array( 'name'=>"PredefinedInvoices", 'title'=>"ListPredefinedInvoicesAssociatedProject", @@ -423,7 +423,7 @@ $listofreferent = array( 'lang'=>'bills', 'buttonnew'=>'CreateBill', 'testnew'=>$user->hasRight('facture', 'creer'), - 'test'=>!empty($conf->facture->enabled) && $user->hasRight('facture', 'lire')), + 'test'=>isModEnabled('facture') && $user->hasRight('facture', 'lire')), 'proposal_supplier'=>array( 'name'=>"SuppliersProposals", 'title'=>"ListSupplierProposalsAssociatedProject", @@ -616,7 +616,7 @@ $listofreferent = array( 'lang'=>'banks', 'buttonnew'=>'AddVariousPayment', 'testnew'=>$user->hasRight('banque', 'modifier'), - 'test'=>!empty($conf->banque->enabled) && $user->hasRight('banque', 'lire') && !empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)), + 'test'=>isModEnabled("banque") && $user->hasRight('banque', 'lire') && !empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)), /* No need for this, available on dedicated tab "Agenda/Events" 'agenda'=>array( 'name'=>"Agenda", @@ -629,7 +629,7 @@ $listofreferent = array( 'lang'=>'agenda', 'buttonnew'=>'AddEvent', 'testnew'=>$user->rights->agenda->myactions->create, - 'test'=>$conf->agenda->enabled && $user->rights->agenda->myactions->read), + 'test'=> isModEnabled('agenda') && $user->rights->agenda->myactions->read), */ ); @@ -1260,6 +1260,10 @@ foreach ($listofreferent as $key => $value) { if (!empty($element->ref_customer)) { print ' - '.$element->ref_customer; } + // Compatibility propale + if (empty($element->ref_customer) && !empty($element->ref_client)) { + print ' - '.$element->ref_client; + } } print "\n"; diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index 6e39b629347..aa40ba4bc5a 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -394,7 +394,7 @@ if ($resql) { if ($othernb) { print ''; print ''; - print '...'; + print ''.$langs->trans("More").'...'; print ''; print ''; print $othernb; @@ -412,10 +412,9 @@ if ($resql) { dol_print_error($db); } -if (empty($conf->global->PROJECT_HIDE_PROJECT_LIST_ON_PROJECT_AREA)) { - // This list can be very long, so we allow to hide it to prefer to use the list page. - // Add constant PROJECT_HIDE_PROJECT_LIST_ON_PROJECT_AREA to hide this list - +if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') || getDolGlobalInt('PROJECT_SHOW_OPEN_PROJECTS_LIST_ON_PROJECT_AREA')) { + // This list is surely very long and useless when we are using opportunities, so we hide it for this use case, but we allow to show it if + // we really want it and to allow interface backward compatibility. print '
'; print_projecttasks_array($db, $form, $socid, $projectsListId, 0, 1, $listofoppstatus, array()); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 1d38e5214d5..b55305c92e6 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -425,7 +425,7 @@ if (count($listofprojectcontacttypeexternal) == 0) { $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields -$distinct = 'DISTINCT'; // We add distinct until we have added a protection to be sure a contact of a project and task is only once. +$distinct = 'DISTINCT'; // We add distinct until filter on contact of project or task is implemented with AND EXISTS $sql = "SELECT ".$distinct." p.rowid as id, p.ref, p.title, p.fk_statut as status, p.fk_opp_status, p.public, p.fk_user_creat,"; $sql .= " p.datec as date_creation, p.dateo as date_start, p.datee as date_end, p.opp_amount, p.opp_percent, (p.opp_amount*p.opp_percent/100) as opp_weighted_amount, p.tms as date_update, p.budget_amount,"; $sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,"; @@ -473,7 +473,7 @@ if ($search_project_contact > 0) { $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -$sql .= " WHERE p.entity IN (".getEntity('project').')'; +$sql .= " WHERE p.entity IN (".getEntity('project', (GETPOST('search_current_entity', 'int') ? 0 : 1)).')'; if (empty($user->rights->projet->all->lire)) { $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId).")"; // public and assigned to, or restricted to company for external users } @@ -506,7 +506,6 @@ if ($search_opp_percent) { $sql .= dolSqlDateFilter('p.dateo', $search_sday, $search_smonth, $search_syear); $sql .= dolSqlDateFilter('p.datee', $search_eday, $search_emonth, $search_eyear); - if ($search_date_start_start) { $sql .= " AND p.dateo >= '".$db->idate($search_date_start_start)."'"; } @@ -742,7 +741,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_all != '') { $param .= '&search_all='.urlencode($search_all); @@ -989,7 +988,7 @@ $moreforfilter .= '
'; $moreforfilter .= '
'; $tmptitle = $langs->trans('ProjectsWithThisContact'); -$moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->selectcontacts(0, $search_project_contact ? $search_project_contact : '', 'search_project_contact', $tmptitle, '', '', 0, 'maxwidth250 widthcentpercentminusx'); +$moreforfilter .= img_picto($tmptitle, 'contact', 'class="pictofixedwidth"').$form->selectcontacts(0, $search_project_contact ? $search_project_contact : '', 'search_project_contact', $tmptitle, '', '', 0, 'maxwidth250 widthcentpercentminusx'); $moreforfilter .= '
'; // If the user can view thirdparties other than his' @@ -1007,7 +1006,7 @@ if (isModEnabled('categorie') && $user->rights->categorie->lire) { $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PROJECT, $search_category_array, 'minwidth300imp widthcentpercentminusx'); } // Filter on customer categories -if (!empty($conf->global->MAIN_SEARCH_CATEGORY_CUSTOMER_ON_PROJECT_LIST) && !empty($conf->categorie->enabled) && $user->rights->categorie->lire) { +if (!empty($conf->global->MAIN_SEARCH_CATEGORY_CUSTOMER_ON_PROJECT_LIST) && isModEnabled("categorie") && $user->rights->categorie->lire) { $moreforfilter .= '
'; $tmptitle = $langs->transnoentities('CustomersProspectsCategoriesShort'); $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); @@ -1029,7 +1028,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); @@ -1254,7 +1253,7 @@ $totalarray['nbfield'] = 0; // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } if (!empty($arrayfields['p.ref']['checked'])) { @@ -1377,7 +1376,7 @@ if (!empty($arrayfields['p.fk_statut']['checked'])) { } // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } print ''."\n"; @@ -1410,7 +1409,7 @@ while ($i < $imaxinloop) { $object->opp_percent = $obj->opp_percent; $object->opp_status = $obj->fk_opp_status; $object->opp_status_code = $obj->opp_status_code; - $object->opp_amount = !empty($obj->opp_ammount) ? $obj->opp_ammount : ""; + $object->opp_amount = !empty($obj->opp_amount) ? $obj->opp_amount : ""; $object->opp_weighted_amount = $obj->opp_weighted_amount; $object->budget_amount = $obj->budget_amount; $object->usage_opportunity = $obj->usage_opportunity; @@ -1469,7 +1468,7 @@ while ($i < $imaxinloop) { } // Project url if (!empty($arrayfields['p.ref']['checked'])) { - print ''; + print ''; print $object->getNomUrl(1, (!empty(GETPOST('search_usage_event_organization', 'int'))?'eventorganization':'')); if ($object->hasDelay()) { print img_warning($langs->trans('Late')); @@ -1859,10 +1858,12 @@ while ($i < $imaxinloop) { } // Email MsgID if (!empty($arrayfields['p.email_msgid']['checked'])) { - print ''; - print $obj->email_msgid; + print ''; + print dol_escape_htmltag($obj->email_msgid); print ''; - if (!$i) $totalarray['nbfield']++; + if (!$i) { + $totalarray['nbfield']++; + } } // Import key if (!empty($arrayfields['p.import_key']['checked'])) { diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 35e47f64604..fdbe705b928 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -162,8 +162,8 @@ $arrayfields = array( '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), - 's.name_alias'=>array('label'=>"AliasNameShort", 'checked'=>1), + 's.nom'=>array('label'=>"ThirdParty", 'checked'=>0, 'csslist'=>'tdoverflowmax125'), + 's.name_alias'=>array('label'=>"AliasNameShort", 'checked'=>1, 'csslist'=>'tdoverflowmax125'), '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), @@ -186,6 +186,8 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); $permissiontoread = $user->rights->projet->lire; $permissiontodelete = $user->rights->projet->supprimer; +if (!$permissiontoread) accessforbidden(); + /* * Actions @@ -266,18 +268,19 @@ if (empty($search_projectstatus) && $search_projectstatus == '') { */ $form = new Form($db); - -$now = dol_now(); - -$help_url = "EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; -$morejs = array(); -$morecss = array(); - $formother = new FormOther($db); $socstatic = new Societe($db); $projectstatic = new Project($db); $puser = new User($db); $tuser = new User($db); + +$now = dol_now(); + +$title = $langs->trans("Activities"); +$help_url = "EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; +$morejs = array(); +$morecss = array(); + if ($search_project_user > 0) { $puser->fetch($search_project_user); } @@ -290,9 +293,6 @@ $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields -$title = $langs->trans("Activities"); -//if ($search_task_user == $user->id) $title=$langs->trans("MyActivities"); - if ($id) { $projectstatic->fetch($id); $projectstatic->fetch_thirdparty(); @@ -337,6 +337,8 @@ if (count($listoftaskcontacttype) == 0) { $listoftaskcontacttype[0] = '0'; // To avoid sql syntax error if not found } +// Build and execute select +// -------------------------------------------------------------------- $distinct = 'DISTINCT'; // We add distinct until we are added a protection to be sure a contact of a project and task is assigned only once. $sql = "SELECT ".$distinct." p.rowid as projectid, p.ref as projectref, p.title as projecttitle, p.fk_statut as projectstatus, p.datee as projectdatee, p.fk_opp_status, p.public, p.fk_user_creat as projectusercreate, p.usage_bill_time,"; $sql .= " s.nom as name, s.name_alias as alias, s.rowid as socid,"; @@ -356,8 +358,12 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { } // Add fields from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); + +$sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; @@ -525,7 +531,7 @@ if ($searchCategoryCustomerOperator == 1) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) { $sql .= " GROUP BY p.rowid, p.ref, p.title, p.fk_statut, p.datee, p.fk_opp_status, p.public, p.fk_user_creat,"; @@ -539,21 +545,33 @@ if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed } } } -$sql .= $db->order($sortfield, $sortorder); +// Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -$sql .= $db->plimit($limit + 1, $offset); - -dol_syslog("list allowed project", LOG_DEBUG); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} $resql = $db->query($sql); if (!$resql) { @@ -576,7 +594,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist'); // Can use also classforhorizontalscrolloftabs instead of bodyforlist for no horizontal scroll $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -588,7 +606,7 @@ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_date_startday) { $param .= '&search_date_startday='.urlencode($search_date_startday); @@ -693,7 +711,7 @@ $arrayofmassactions = array( // 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); -if ($permissiontodelete) { +if (!empty($permissiontodelete)) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { @@ -701,12 +719,6 @@ if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'pr } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); -$newcardbutton = ''; - -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); -$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); -$newcardbutton .= dolGetButtonTitle($langs->trans('NewTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?action=create', '', $user->rights->projet->creer); - print '
'."\n"; if ($optioncss != '') { print ''; @@ -716,13 +728,22 @@ print ''; print ''; print ''; print ''; +print ''; if (!empty($type)) { print ''; } print ''; +print ''; print ''; +$newcardbutton = ''; + +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); +$newcardbutton .= dolGetButtonTitle($langs->trans('NewTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?action=create', '', $user->rights->projet->creer); + + // Show description of content $texthelp = ''; if ($search_task_user == $user->id) { @@ -744,10 +765,13 @@ $trackid = 'tas'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { + $setupstring = ''; foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key."=".$val.";"; } - print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'; + print ''."\n"; + print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'."\n"; } $moreforfilter = ''; @@ -782,7 +806,7 @@ $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form- $moreforfilter .= '
'; // Filter on customer categories -if (!empty($conf->global->MAIN_SEARCH_CATEGORY_CUSTOMER_ON_TASK_LIST) && !empty($conf->categorie->enabled) && $user->rights->categorie->lire) { +if (!empty($conf->global->MAIN_SEARCH_CATEGORY_CUSTOMER_ON_TASK_LIST) && isModEnabled("categorie") && $user->rights->categorie->lire) { $moreforfilter .= '
'; $tmptitle = $langs->transnoentities('CustomersProspectsCategoriesShort'); $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); @@ -798,24 +822,24 @@ if (!empty($moreforfilter)) { print '
'; print $moreforfilter; $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
'; } -if ($massactionbutton) { - $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); -} +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields +$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); -print '
'; +print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''."\n"; // Fields title search // -------------------------------------------------------------------- print ''; // Action column -if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { - print ''; @@ -930,7 +954,7 @@ if (!empty($arrayfields['t.billed']['checked'])) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['t.datec']['checked'])) { // Date creation @@ -943,8 +967,8 @@ if (!empty($arrayfields['t.tms']['checked'])) { print ''; } // Action column -if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { - print ''; @@ -973,8 +997,10 @@ $totalarray = array( // Fields title label // -------------------------------------------------------------------- print ''; -if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; } if (!empty($arrayfields['t.fk_task_parent']['checked'])) { print_liste_field_titre($arrayfields['t.fk_task_parent']['label'], $_SERVER["PHP_SELF"], "t.fk_task_parent", "", $param, "", $sortfield, $sortorder); @@ -1072,10 +1098,11 @@ if (!empty($arrayfields['t.tms']['checked'])) { print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER["PHP_SELF"], "t.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap '); $totalarray['nbfield']++; } -if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +// Action column +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; } -$totalarray['nbfield']++; print ''."\n"; $plannedworkloadoutputformat = 'allhourmin'; @@ -1091,6 +1118,7 @@ if (!empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) { // -------------------------------------------------------------------- $i = 0; $savnbfield = $totalarray['nbfield']; +$totalarray = array(); $totalarray['nbfield'] = 0; $imaxinloop = ($limit ? min($num, $limit) : $num); while ($i < $imaxinloop) { @@ -1131,9 +1159,16 @@ while ($i < $imaxinloop) { print '
'; } // Output Kanban - $object->fk_statut = $projectstatic->getLibStatut(1); - $object->fk_project = $projectstatic->getNomUrl(1, 'task'); - print $object->getKanbanView(''); + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + } + + $arraydata = array(); + $arraydata['projectlink'] = $projectstatic->getNomUrl(1); + print $object->getKanbanView('', $arraydata); if ($i == ($imaxinloop - 1)) { print '
'; print ''; @@ -1141,10 +1176,12 @@ while ($i < $imaxinloop) { } else { $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { + // Show here line of result + $j = 0; print ''; // Action column - if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Ref Parent if (!empty($arrayfields['t.fk_task_parent']['checked'])) { @@ -1238,8 +1278,8 @@ while ($i < $imaxinloop) { } // Project title if (!empty($arrayfields['p.title']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -1247,7 +1287,7 @@ while ($i < $imaxinloop) { } // Third party if (!empty($arrayfields['s.nom']['checked'])) { - print ''; }*/ // Action column - if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print ''; - } - if (!$i) { - $totalarray['nbfield']++; + if (!$i) { + $totalarray['nbfield']++; + } } print ''."\n"; @@ -1554,7 +1594,7 @@ if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['tota $db->free($resql); $parameters = array('arrayfields'=>$arrayfields, 'sql' => $sql); -$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
'; +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; $searchpicto = $form->showFilterButtons('left'); print $searchpicto; print ''; +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; $searchpicto = $form->showFilterButtons(); print $searchpicto; print '
'; if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; @@ -1154,6 +1191,9 @@ while ($i < $imaxinloop) { print ''; } print ''; - print dol_trunc($obj->projecttitle, 80); + print ''; + print dol_escape_htmltag($obj->projecttitle); print ''; + print ''; if ($obj->socid) { print $socstatic->getNomUrl(1, '', 0, 0, -1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1); } else { @@ -1260,7 +1300,7 @@ while ($i < $imaxinloop) { } // Alias if (!empty($arrayfields['s.name_alias']['checked'])) { - print ''; + print ''; if ($obj->socid) { print $socstatic->name_alias; } else { @@ -1452,8 +1492,8 @@ while ($i < $imaxinloop) { // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['t.datec']['checked'])) { @@ -1480,7 +1520,7 @@ while ($i < $imaxinloop) { print ''.$projectstatic->getLibStatut(5).''; if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; @@ -1490,9 +1530,9 @@ while ($i < $imaxinloop) { print ''; } print '
'."\n"; diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 12eb7c573ce..0da51607eb8 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -149,7 +149,6 @@ if ($object->fk_project > 0) { } - /* * Actions */ @@ -875,9 +874,11 @@ if ($action == 'confirm_generateinter') { } } + /* * View */ + $form = new Form($db); $formother = new FormOther($db); $formproject = new FormProjets($db); @@ -1296,7 +1297,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $param .= '&contextpage='.urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit='.((int) $limit); } if ($search_month > 0) { $param .= '&search_month='.urlencode($search_month); @@ -1304,7 +1305,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($search_year > 0) { $param .= '&search_year='.urlencode($search_year); } - if ($search_user > 0) { + if (!empty($search_user)) { // We keep param if -1 because default value is forced to user id if not set $param .= '&search_user='.urlencode($search_user); } if ($search_task_ref != '') { @@ -1457,7 +1458,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; print ''; - if ($conf->service->enabled) { + if (isModEnabled("service")) { print ''; print ''; print $langs->trans('ServiceToUseOnLines'); @@ -1564,6 +1565,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql = preg_replace('/,\s*$/', '', $sql); + + $sqlfields = $sql; // $sql fields to remove for count total + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facturedet as il ON il.rowid = t.invoice_line_id"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as inv ON inv.rowid = il.fk_facture"; @@ -1657,39 +1661,42 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; - $sql .= $db->order($sortfield, $sortorder); // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $resql = $db->query($sql); - - if (! $resql) { + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql); + $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount); + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { dol_print_error($db); - exit; } - $nbtotalofrecords = $db->num_rows($resql); - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } - // if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. - if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) { - $num = $nbtotalofrecords; - } else { + + // Complete request and execute it with limit + $sql .= $db->order($sortfield, $sortorder); + if ($limit) { $sql .= $db->plimit($limit + 1, $offset); - - $resql = $db->query($sql); - if (!$resql) { - dol_print_error($db); - exit; - } - - $num = $db->num_rows($resql); } + $resql = $db->query($sql); + if (!$resql) { + dol_print_error($db); + exit; + } + + $num = $db->num_rows($resql); + if ($num >= 0) { if (!empty($projectidforalltimes)) { print ''."\n"; @@ -1743,7 +1750,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) { print ''; - if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { + if (isModEnabled("service") && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { print ''.$langs->trans("Product").''; } } @@ -1790,7 +1797,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($projectstatic->public) { $contactsofproject = array(); } - print $form->select_dolusers((GETPOST('userid', 'int') ? GETPOST('userid', 'int') : $userid), 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, $langs->trans("ResourceNotAssignedToProject"), 'maxwidth250'); + print $form->select_dolusers((GETPOST('userid', 'int') ? GETPOST('userid', 'int') : $userid), 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, $langs->trans("ResourceNotAssignedToProject"), 'maxwidth200'); } else { if ($nboftasks) { print img_error($langs->trans('FirstAddRessourceToAllocateTime')).' '.$langs->trans('FirstAddRessourceToAllocateTime'); @@ -1822,9 +1829,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; print ''; - if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { - print ''; - print $form->select_produits('', 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500'); + if (isModEnabled("service") && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { + print ''; + print img_picto('', 'product'); + print $form->select_produits('', 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 1, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth150', 0, '', null, 1); print ''; } } @@ -1836,7 +1844,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; $form->buttonsSaveCancel(); - print ''; + print ''; print ''; print ''; @@ -1870,6 +1878,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''."\n"; // Fields title search + // -------------------------------------------------------------------- print ''; // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { @@ -1918,7 +1927,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Author if (!empty($arrayfields['author']['checked'])) { - print ''; + print ''; } // Note if (!empty($arrayfields['t.note']['checked'])) { @@ -1977,54 +1986,72 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } print ''."\n"; + $totalarray = array(); + $totalarray['nbfield'] = 0; + + // Fields title label + // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); + $totalarray['nbfield']++; } if (!empty($arrayfields['t.element_date']['checked'])) { print_liste_field_titre($arrayfields['t.element_date']['label'], $_SERVER['PHP_SELF'], 't.element_date,t.element_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } - if (!empty($arrayfields['p.fk_soc']['checked'])) { print_liste_field_titre($arrayfields['p.fk_soc']['label'], $_SERVER['PHP_SELF'], 't.element_date,t.element_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['s.name_alias']['checked'])) { print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER['PHP_SELF'], 's.name_alias', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($allprojectforuser)) { if (!empty($arrayfields['p.project_ref']['checked'])) { print_liste_field_titre("Project", $_SERVER['PHP_SELF'], 'p.ref', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['p.project_label']['checked'])) { print_liste_field_titre("ProjectLabel", $_SERVER['PHP_SELF'], 'p.title', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } } if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task if (!empty($arrayfields['t.element_ref']['checked'])) { print_liste_field_titre($arrayfields['t.element_ref']['label'], $_SERVER['PHP_SELF'], 'pt.ref', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['t.element_label']['checked'])) { print_liste_field_titre($arrayfields['t.element_label']['label'], $_SERVER['PHP_SELF'], 'pt.label', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } } if (!empty($arrayfields['author']['checked'])) { print_liste_field_titre($arrayfields['author']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['t.note']['checked'])) { print_liste_field_titre($arrayfields['t.note']['label'], $_SERVER['PHP_SELF'], 't.note', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['t.element_duration']['checked'])) { print_liste_field_titre($arrayfields['t.element_duration']['label'], $_SERVER['PHP_SELF'], 't.element_duration', '', $param, '', $sortfield, $sortorder, 'right '); + $totalarray['nbfield']++; } if (!empty($arrayfields['t.fk_product']['checked'])) { print_liste_field_titre($arrayfields['t.fk_product']['label'], $_SERVER['PHP_SELF'], 't.fk_product', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['value']['checked'])) { print_liste_field_titre($arrayfields['value']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right '); + $totalarray['nbfield']++; } if (!empty($arrayfields['valuebilled']['checked'])) { print_liste_field_titre($arrayfields['valuebilled']['label'], $_SERVER['PHP_SELF'], 'il.total_ht', '', $param, '', $sortfield, $sortorder, 'center ', $langs->trans("SelectLinesOfTimeSpentToInvoice")); + $totalarray['nbfield']++; } /* // Extra fields @@ -2036,6 +2063,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print $hookmanager->resPrint; if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch '); + $totalarray['nbfield']++; } print "\n"; @@ -2043,10 +2071,13 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $tmpinvoice = new Facture($db); $i = 0; - $total = 0; $totalvalue = 0; - $totalarray = array('nbfield'=>0); + + $savnbfield = $totalarray['nbfield']; + $totalarray = array(); + $totalarray['nbfield'] = 0; + //$imaxinloop = ($limit ? min($num, $limit) : $num); foreach ($tasks as $task_time) { if ($i >= $limit) { break; @@ -2055,11 +2086,13 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $date1 = $db->jdate($task_time->element_date); $date2 = $db->jdate($task_time->element_datehour); - print ''; + // Show here line of result + $j = 0; + print ''; // Action column if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Date if (!empty($arrayfields['t.element_date']['checked'])) { @@ -2113,7 +2150,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Thirdparty if (!empty($arrayfields['p.fk_soc']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -2294,9 +2332,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } - //Product + // Product if (!empty($arrayfields['t.fk_product']['checked'])) { - print ''; + if (!$i) { + $totalarray['nbfield']++; + } } // Value spent @@ -2392,9 +2433,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; - if (!$i) { - $totalarray['nbfield']++; + print ''; + if (!$i) { + $totalarray['nbfield']++; + } } print "\n"; @@ -2434,6 +2475,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Add line to split if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { + print ''; print ''; // Date @@ -2451,6 +2493,18 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } + // Thirdparty + if (!empty($arrayfields['p.fk_soc']['checked'])) { + print ''; + } + + // Thirdparty alias + if (!empty($arrayfields['s.name_alias']['checked'])) { + print ''; + } + // Project ref if (!empty($allprojectforuser)) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task @@ -2482,7 +2536,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // User if (!empty($arrayfields['author']['checked'])) { - print ''; } + // Product + if (!empty($arrayfields['t.fk_product']['checked'])) { + print ''; + } + // Value spent if (!empty($arrayfields['value']['checked'])) { print ''; + print ''; // Date if (!empty($arrayfields['t.element_date']['checked'])) { @@ -2589,6 +2649,18 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } + // Thirdparty + if (!empty($arrayfields['p.fk_soc']['checked'])) { + print ''; + } + + // Thirdparty alias + if (!empty($arrayfields['s.name_alias']['checked'])) { + print ''; + } + // Project ref if (!empty($allprojectforuser)) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task @@ -2613,14 +2685,14 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; } } // User if (!empty($arrayfields['author']['checked'])) { - print ''; } + // Product + if (!empty($arrayfields['t.fk_product']['checked'])) { + print ''; + } + // Value spent if (!empty($arrayfields['value']['checked'])) { print ''; } else { - print ''; + print ''; } } elseif ($totalarray['totaldurationfield'] == $i) { print ''; diff --git a/htdocs/public/agenda/agendaexport.php b/htdocs/public/agenda/agendaexport.php index e8d9f986f91..e9bca76cdbc 100644 --- a/htdocs/public/agenda/agendaexport.php +++ b/htdocs/public/agenda/agendaexport.php @@ -84,7 +84,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; // Security check -if (empty($conf->agenda->enabled)) { +if (!isModEnabled('agenda')) { httponly_accessforbidden('Module Agenda not enabled'); } diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php index f7274d5b06b..c71f1d86dc7 100644 --- a/htdocs/public/demo/index.php +++ b/htdocs/public/demo/index.php @@ -434,7 +434,7 @@ print '
'; // TODO Replace this with a hook // Google Adsense (need Google module) -if (!empty($conf->google->enabled) && !empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && !empty($conf->global->MAIN_GOOGLE_AD_SLOT)) { +if (isModEnabled('google') && !empty($conf->global->MAIN_GOOGLE_AD_CLIENT) && !empty($conf->global->MAIN_GOOGLE_AD_SLOT)) { if (empty($conf->dol_use_jmobile)) { print '
'."\n"; print '
'.$form->select_dolusers(($search_user > 0 ? $search_user : -1), 'search_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth250').''.$form->select_dolusers(($search_user > 0 ? $search_user : -1), 'search_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth150').'
'; + print ''; if (($action == 'editline' || $action == 'splitline') && GETPOST('lineid', 'int') == $task_time->rowid) { print ''; print ''; @@ -2092,6 +2125,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } } + print ''; + print ''; if ($task_time->fk_soc > 0) { if (empty($conf->cache['thridparty'][$task_time->fk_soc])) { $tmpsociete = new Societe($db); @@ -2132,7 +2169,6 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Thirdparty alias if (!empty($arrayfields['s.name_alias']['checked'])) { - print ''; if ($task_time->fk_soc > 0) { if (empty($conf->cache['thridparty'][$task_time->fk_soc])) { $tmpsociete = new Societe($db); @@ -2141,8 +2177,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } else { $tmpsociete = $conf->cache['thridparty'][$task_time->fk_soc]; } - print $tmpsociete->name_alias; + $valtoshow = $tmpsociete->name_alias; } + print ''; + print $valtoshow; print ''; + print ''; if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) { $form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500'); } elseif (!empty($task_time->fk_product)) { @@ -2309,6 +2347,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } print ''; if (($action == 'editline' || $action == 'splitline') && GETPOST('lineid', 'int') == $task_time->rowid) { print ''; - print ''; + print ''; print ' '; - print ''; + print ''; } elseif ($user->hasRight('projet', 'time') || $user->hasRight('projet', 'all', 'creer')) { // Read project and enter time consumed on assigned tasks if (in_array($task_time->fk_user, $childids) || $user->hasRight('projet', 'all', 'creer')) { if (getDolGlobalString('MAIN_FEATURES_LEVEL') >= 2) { @@ -2422,10 +2463,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } } - } - print '
'; + print ''; + print ''; + print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { if (empty($object->id)) { $object->fetch($id); @@ -2533,6 +2587,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; + print ''; @@ -2572,7 +2632,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Line for second dispatching - print '
'; + print ''; + print ''; - print $task_time->label; + print dol_escape_htmltag($task_time->label); print ''; + print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { if (empty($object->id)) { $object->fetch($id); @@ -2671,6 +2743,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; + print ''; @@ -2724,7 +2802,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($num < $limit && empty($offset)) { print ''.$langs->trans("Total").''.$langs->trans("Totalforthispage").''.$form->textwithpicto($langs->trans("Total"), $langs->trans("Totalforthispage")).''.convertSecondToTime($totalarray['totalduration'], 'allhourmin').'